Pikeを使ってTerraform実行ユーザー用の最小限のIAMポリシーを生成する
「terraform apply を実行するユーザーやロールにも最小限の権限を付与するようにしたい。」
Terraformで色々管理しているから、Terraform実行ユーザーの権限は強めにしているけど少し不安。最小限の権限を割り当てる方法はないかな?
そんな時には、Pikeを使ってみるのもいいかもしれません。
Pikeとは
一言で言うと、TerraformのコードからTerraform実行に必要な最小限のIAMポリシーを生成してくれるツールです。
JamesWoolfenden/pike: Pike is a tool for determining the permissions or policy required for IAC code
Terraform実行用IAMユーザー・IAMロールの権限
例えば、TerraformでAWSインフラを管理しているとします。
terraform apply
を実行するために、AWSリソースを操作する権限を持ったIAMユーザーやIAMロールが必要になります。
このIAMユーザーやIAMロールに渡す権限ですが、理想は最小限の権限であるべきです。 しかし、Terraformで管理するリソースが増えてくると最小限の運用の手間は大きいです。
そのため、セキュリティ的には良くないと分かっていても、Terraform実行用のIAMユーザーやIAMロールにはAdministratorAccess
などの強い権限のIAMポリシーを付与して運用することが多いかと思います。
Pikeを使うと
Pikeを使えば、Terraformのコードからterraform apply
に必要な最小限のIAMポリシーを作成するといったことができます。
以下は実行例です。 Pikeはterraformをサポートしていて、AWSプロパイダー以外にもGoogle CloudやAzureのプロパイダーもサポートしています。(2022/12/12時点)
$pike scan -o terraform -d ../modules/aws/terraform-aws-activemq resource "aws_iam_policy" "terraformXVlBzgba" { name = "terraformXVlBzgba" path = "/" description = "Add Description" policy = jsonencode({ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "ec2:AuthorizeSecurityGroupEgress", "ec2:AuthorizeSecurityGroupIngress", "ec2:CreateNetworkInterface", "ec2:CreateNetworkInterfacePermission", "ec2:CreateSecurityGroup", "ec2:CreateTags", "ec2:DeleteNetworkInterface", "ec2:DeleteNetworkInterfacePermission", "ec2:DeleteSecurityGroup", "ec2:DeleteTags", "ec2:DescribeAccountAttributes", "ec2:DescribeInternetGateways", "ec2:DescribeNetworkInterfaces", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVpcs", "ec2:DetachNetworkInterface", "ec2:RevokeSecurityGroupEgress", "ec2:RevokeSecurityGroupIngress" ], "Resource": "*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "kms:CreateKey", "kms:DescribeKey", "kms:EnableKeyRotation", "kms:GetKeyPolicy", "kms:GetKeyRotationStatus", "kms:ListResourceTags", "kms:ScheduleKeyDeletion", "kms:TagResource", "kms:UntagResource" ], "Resource": "*" }, { "Sid": "VisualEditor2", "Effect": "Allow", "Action": [ "mq:CreateBroker", "mq:CreateConfiguration", "mq:CreateTags", "mq:CreateUser", "mq:DeleteBroker", "mq:DeleteTags", "mq:DeleteUser", "mq:DescribeBroker", "mq:DescribeConfiguration", "mq:DescribeConfigurationRevision", "mq:DescribeUser", "mq:RebootBroker", "mq:UpdateBroker", "mq:UpdateConfiguration", "mq:UpdateUser" ], "Resource": "*" } ] }) }
試してみる
サンプルコード
DynamoDBとSQSのモジュールを作って、main.tf
で呼び出すようにしています。
ディレクトリ構成は以下になっています。
このサンプルコードを使って、Pikeではどのようにポリシーが生成されるか見ていきます。
├── backend.tfvars ├── main.tf ├── module │ ├── dynamodb │ │ └── main.tf │ └── sqs │ └── main.tf └── provider.tf
module "sqs" { source = "./module/sqs" } module "dynamodb" { source = "./module/dynamodb" }
resource "aws_sqs_queue" "this" { name = "terraform-example-queue" }
resource "aws_dynamodb_table" "this" { hash_key = "partition_key" range_key = "sort_key" attribute { name = "partition_key" type = "S" } attribute { name = "sort_key" type = "S" } }
インストール
brewでインストールできます。
$ brew tap jameswoolfenden/homebrew-tap $ brew install jameswoolfenden/tap/pike
ポリシーを生成してみる
まずは、モジュールを呼び出すmain.tf
があるディレクトリでPikeを実行してみます。
$ pike scan . resource "aws_iam_policy" "terraform_pike" { name_prefix = "terraform_pike" path = "/" description = "Pike Autogenerated policy from IAC" policy = jsonencode({ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "dynamodb:CreateTable", "dynamodb:DeleteTable", "dynamodb:DescribeContinuousBackups", "dynamodb:DescribeTable", "dynamodb:DescribeTimeToLive", "dynamodb:ListTagsOfResource", "dynamodb:UpdateTable", "dynamodb:UpdateTimeToLive" ], "Resource": [ "*" ] }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "sqs:CreateQueue", "sqs:DeleteQueue", "sqs:GetQueueAttributes", "sqs:ListQueueTags", "sqs:SetQueueAttributes" ], "Resource": [ "*" ] } ] }) }
ディレクトリを指定して実行可能なので、module単位でポリシーを作成することもできます。
pike scan -d module/dynamodb resource "aws_iam_policy" "terraform_pike" { name_prefix = "terraform_pike" path = "/" description = "Pike Autogenerated policy from IAC" policy = jsonencode({ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "dynamodb:CreateTable", "dynamodb:DeleteTable", "dynamodb:DescribeContinuousBackups", "dynamodb:DescribeTable", "dynamodb:DescribeTimeToLive", "dynamodb:ListTagsOfResource", "dynamodb:UpdateTable", "dynamodb:UpdateTimeToLive" ], "Resource": [ "*" ] } ] }) }
生成したポリシーをデプロイする
ポリシーを生成できることが分かったので、ポリシーを実際にデプロイしてみます。
$ pike make . 3:30PM DBG terraform init at /Users/sato.masaki/work/src/github.com/msato0731/terraform-sample/pike-demo 3:30PM DBG aws role create/updated arn:aws:iam::111111111111111:role/terraform_pike_20221214063044638700000002 3:30PM DBG arn:aws:iam::111111111111111:role/terraform_pike_20221214063044638700000002
コマンドを実行するとIAMロールとIAMポリシーが作成されます。
Pikeを使うことで、簡単にIAMポリシーの生成ができました。
コマンド実行後に、ディレクトリを確認すると以下のように.pike
ディレクトリが作成されていてIAMポリシーとロールを作成するためのtfファイルが作成されました。
pike makeではこのtfファイルを使って、IAMポリシーとロールを作成しています。
$ tree -a -L 2 ├── .pike │ ├── .terraform │ ├── .terraform.lock.hcl │ ├── aws_iam_role.terraform_pike.tf │ ├── pike.generated_policy.tf │ ├── terraform.tfstate │ └── terraform.tfstate.backup ├── .terraform │ ├── modules │ ├── providers │ └── terraform.tfstate ├── .terraform.lock.hcl ├── backend.tfvars ├── main.tf ├── module │ ├── dynamodb │ └── sqs └── provider.tf
おわりに
TerraformのコードからIAMポリシー生成してくれるツールPikeの紹介でした。
臼田さんから教えてもらって面白いツールだなと思ったのでブログにしました。
Terraform実行ユーザーのIAMポリシーに悩んでいる方の助けになるツールかと思います。
現在(2022/12/14時点)は一部機能が、AWS Providerのみに対応しているようです。
今後の発展が楽しみなツールです。
以上、AWS事業本部の佐藤(@chari7311)でした。