diff --git a/iac-template/terraform-standard/bootstrap-iam/.gitignore b/iac-template/terraform-standard/bootstrap-iam/.gitignore index 5e697082..e8ee7ab9 100644 --- a/iac-template/terraform-standard/bootstrap-iam/.gitignore +++ b/iac-template/terraform-standard/bootstrap-iam/.gitignore @@ -18,6 +18,7 @@ terraform.tfstate.backup .aws/ credentials config +.bootstrap.env # OS-specific .DS_Store diff --git a/iac-template/terraform-standard/bootstrap-iam/Makefile b/iac-template/terraform-standard/bootstrap-iam/Makefile index a6af46c8..ec2e0139 100644 --- a/iac-template/terraform-standard/bootstrap-iam/Makefile +++ b/iac-template/terraform-standard/bootstrap-iam/Makefile @@ -1,15 +1,24 @@ +account_name ?= dev +region ?= ap-northeast-1 +role_name ?= TerraformDeployRole-Dev +terraform_user_name ?= sit-ci-runner + init: terraform init --upgrade apply: init - terraform apply \ - -var="region=ap-northeast-1" \ - -var="account_name=dev" \ - -var="role_name=TerraformDeployRole-Dev" \ - -auto-approve + terraform apply -auto-approve \ + -var="account_name=$(account_name)" \ + -var="region=$(region)" \ + -var="role_name=$(role_name)" \ + -var="terraform_user_name=$(terraform_user_name)" terraform output plan: init terraform plan -var="region=ap-northeast-1" -var="account_name=dev" -var="role_name=TerraformDeployRole-Dev" output: init terraform output destroy: init - terraform destroy + terraform destroy \ + -var="account_name=$(account_name)" \ + -var="region=$(region)" \ + -var="role_name=$(role_name)" \ + -var="terraform_user_name=$(terraform_user_name)" diff --git a/iac-template/terraform-standard/bootstrap-iam/main.tf b/iac-template/terraform-standard/bootstrap-iam/main.tf index f9c384da..785d7a1f 100644 --- a/iac-template/terraform-standard/bootstrap-iam/main.tf +++ b/iac-template/terraform-standard/bootstrap-iam/main.tf @@ -1,3 +1,12 @@ +locals { + account = yamldecode( + file("${path.root}/../config/accounts/${var.account_name}.yaml") + ) +} + +# +# IAM Role: Terraform Deploy Role +# ---------------------------------------- resource "aws_iam_role" "terraform_deploy_role" { name = var.role_name @@ -6,7 +15,7 @@ resource "aws_iam_role" "terraform_deploy_role" { Statement = [{ Effect = "Allow" Principal = { - AWS = "arn:aws:iam::${local.account.account_id}:root" + AWS = "arn:aws:iam::${local.account.account_id}:user/${var.terraform_user_name}" } Action = "sts:AssumeRole" }] @@ -21,8 +30,69 @@ resource "aws_iam_role" "terraform_deploy_role" { ) } -# 当前阶段给 Admin 权限(你熟悉后可以缩小) +# 可选:当前阶段保持你原来的 Admin full access +# (未来你可以把它缩到最小权限) resource "aws_iam_role_policy_attachment" "attach_admin" { role = aws_iam_role.terraform_deploy_role.name policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" } + +# +# IAM User for Terraform (AK/SK) +# ---------------------------------------- +resource "aws_iam_user" "terraform_user" { + name = var.terraform_user_name +} + +# +# IAM User Policy: 最小权限 +# ---------------------------------------- +resource "aws_iam_user_policy" "terraform_user_policy" { + name = "${var.terraform_user_name}-iac-policy" + user = aws_iam_user.terraform_user.name + + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + # 允许 Assume TerraformDeployRole + { + Effect = "Allow", + Action = [ + "sts:AssumeRole" + ], + Resource = aws_iam_role.terraform_deploy_role.arn + }, + + # S3: Terraform state bucket + { + Effect = "Allow", + Action = [ + "s3:ListBucket" + ], + Resource = "arn:aws:s3:::svc-plus-iac-state" + }, + { + Effect = "Allow", + Action = [ + "s3:GetObject", + "s3:PutObject", + "s3:DeleteObject" + ], + Resource = "arn:aws:s3:::svc-plus-iac-state/*" + }, + + # DynamoDB: state lock table + { + Effect = "Allow", + Action = [ + "dynamodb:GetItem", + "dynamodb:PutItem", + "dynamodb:DeleteItem", + "dynamodb:UpdateItem", + "dynamodb:DescribeTable" + ], + Resource = "arn:aws:dynamodb:${var.region}:${local.account.account_id}:table/svc-plus-iac-state-dynamodb-lock" + } + ] + }) +} diff --git a/iac-template/terraform-standard/bootstrap-iam/outputs.tf b/iac-template/terraform-standard/bootstrap-iam/outputs.tf index 8ee7d701..519a216e 100644 --- a/iac-template/terraform-standard/bootstrap-iam/outputs.tf +++ b/iac-template/terraform-standard/bootstrap-iam/outputs.tf @@ -1,3 +1,9 @@ -output "role_arn" { - value = aws_iam_role.terraform_deploy_role.arn +output "iam_role_arn" { + value = aws_iam_role.terraform_deploy_role.arn + description = "The ARN of the role assumed by Terraform" +} + +output "terraform_user_name" { + value = aws_iam_user.terraform_user.name + description = "Terraform IAM User" } diff --git a/iac-template/terraform-standard/bootstrap-iam/variables.tf b/iac-template/terraform-standard/bootstrap-iam/variables.tf index 2dfb863f..4865cf44 100644 --- a/iac-template/terraform-standard/bootstrap-iam/variables.tf +++ b/iac-template/terraform-standard/bootstrap-iam/variables.tf @@ -13,9 +13,7 @@ variable "role_name" { description = "IAM role name to create (e.g., TerraformDeployRole-Dev)" } -locals { - account = yamldecode( - file("${path.root}/../config/accounts/${var.account_name}.yaml") - ) +variable "terraform_user_name" { + type = string + description = "IAM username for Terraform IAC runner" } - diff --git a/iac-template/terraform-standard/config/accounts/dev.yaml b/iac-template/terraform-standard/config/accounts/dev.yaml index f83fc08d..642cd506 100644 --- a/iac-template/terraform-standard/config/accounts/dev.yaml +++ b/iac-template/terraform-standard/config/accounts/dev.yaml @@ -4,8 +4,7 @@ environment: dev region: ap-northeast-1 -role_to_assume: arn:aws:iam::730335654753:role/TerraformDeployRole-Dev - +role_to_assume: "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" logging_bucket: org-dev-logs shared_vpc_account: "730335654753" # 单账号,所以保持一致 diff --git a/iac-template/terraform-standard/envs/dev/.gitignore b/iac-template/terraform-standard/envs/dev-role/.gitignore similarity index 100% rename from iac-template/terraform-standard/envs/dev/.gitignore rename to iac-template/terraform-standard/envs/dev-role/.gitignore diff --git a/iac-template/terraform-standard/envs/dev/backend.tf b/iac-template/terraform-standard/envs/dev-role/backend.tf similarity index 100% rename from iac-template/terraform-standard/envs/dev/backend.tf rename to iac-template/terraform-standard/envs/dev-role/backend.tf diff --git a/iac-template/terraform-standard/envs/dev/main.tf b/iac-template/terraform-standard/envs/dev-role/main.tf similarity index 100% rename from iac-template/terraform-standard/envs/dev/main.tf rename to iac-template/terraform-standard/envs/dev-role/main.tf diff --git a/iac-template/terraform-standard/envs/dev/outputs.tf b/iac-template/terraform-standard/envs/dev-role/outputs.tf similarity index 67% rename from iac-template/terraform-standard/envs/dev/outputs.tf rename to iac-template/terraform-standard/envs/dev-role/outputs.tf index 567f1a7f..f44c3eb9 100644 --- a/iac-template/terraform-standard/envs/dev/outputs.tf +++ b/iac-template/terraform-standard/envs/dev-role/outputs.tf @@ -1,9 +1,9 @@ output "iam_role_arn" { description = "IAM role ARN created for Terraform deployment" - value = module.iam.role_arn + value = module.dev_role.arn } output "iam_role_name" { description = "IAM role name" - value = module.iam.role_name + value = module.dev_role.name } diff --git a/iac-template/terraform-standard/envs/dev/provider.tf b/iac-template/terraform-standard/envs/dev-role/provider.tf similarity index 100% rename from iac-template/terraform-standard/envs/dev/provider.tf rename to iac-template/terraform-standard/envs/dev-role/provider.tf