From 35ea185df9d2187490f57af872a11eb3a138a2b5 Mon Sep 17 00:00:00 2001 From: cloudneutral Date: Tue, 9 Dec 2025 17:00:54 +0800 Subject: [PATCH] Add render targets to AWS env Makefiles --- .gitignore | 3 + .../aws-cloud/config/provider_backend.yaml | 60 ++++++++++ .../aws-cloud/envs/dev-alb/backend.tf | 8 -- .../aws-cloud/envs/dev-alb/provider.tf | 20 ---- .../aws-cloud/envs/dev-ec2/Makefile | 3 + .../aws-cloud/envs/dev-ec2/backend.tf | 9 -- .../aws-cloud/envs/dev-ec2/provider.tf | 20 ---- .../aws-cloud/envs/dev-kafka/Makefile | 3 + .../aws-cloud/envs/dev-kafka/backend.tf | 9 -- .../aws-cloud/envs/dev-kafka/provider.tf | 20 ---- .../aws-cloud/envs/dev-landingzone/Makefile | 6 + .../aws-cloud/envs/dev-landingzone/backend.tf | 8 -- .../envs/dev-landingzone/provider.tf | 20 ---- .../aws-cloud/envs/dev-nlb/backend.tf | 9 -- .../aws-cloud/envs/dev-nlb/provider.tf | 20 ---- .../aws-cloud/envs/dev-object/Makefile | 4 + .../aws-cloud/envs/dev-object/backend.tf | 9 -- .../aws-cloud/envs/dev-object/provider.tf | 20 ---- .../aws-cloud/envs/dev-rds/Makefile | 4 +- .../aws-cloud/envs/dev-rds/provider.tf | 20 ---- .../aws-cloud/envs/dev-redis/backend.tf | 9 -- .../aws-cloud/envs/dev-redis/provider.tf | 20 ---- .../aws-cloud/envs/dev-role/Makefile | 3 + .../aws-cloud/envs/dev-role/backend.tf | 9 -- .../aws-cloud/envs/dev-role/provider.tf | 20 ---- .../aws-cloud/envs/dev-vpc/Makefile | 3 + .../aws-cloud/envs/dev-vpc/backend.tf | 9 -- .../aws-cloud/envs/dev-vpc/provider.tf | 20 ---- .../aws-cloud/render_provider_backend.py | 107 ++++++++++++++++++ .../aws-cloud/templates/backend.tf.j2 | 8 ++ .../aws-cloud/templates/provider.tf.j2 | 20 ++++ .../terraform-hcl-standard/utils/__init__.py | 0 .../utils/config_loader.py | 86 ++++++++++++++ 33 files changed, 309 insertions(+), 280 deletions(-) create mode 100644 iac-template/terraform-hcl-standard/aws-cloud/config/provider_backend.yaml delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/provider.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/backend.tf delete mode 100644 iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/provider.tf create mode 100644 iac-template/terraform-hcl-standard/aws-cloud/render_provider_backend.py create mode 100644 iac-template/terraform-hcl-standard/aws-cloud/templates/backend.tf.j2 create mode 100644 iac-template/terraform-hcl-standard/aws-cloud/templates/provider.tf.j2 create mode 100644 iac-template/terraform-hcl-standard/utils/__init__.py create mode 100644 iac-template/terraform-hcl-standard/utils/config_loader.py diff --git a/.gitignore b/.gitignore index f536af86..7755b1a1 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,9 @@ coverage.xml .terraform/ *.tfstate *.tfstate.* +# Generated Terraform provider/backend files for AWS cloud envs +iac-template/terraform-hcl-standard/aws-cloud/envs/*/provider.tf +iac-template/terraform-hcl-standard/aws-cloud/envs/*/backend.tf # Ansible *.retry diff --git a/iac-template/terraform-hcl-standard/aws-cloud/config/provider_backend.yaml b/iac-template/terraform-hcl-standard/aws-cloud/config/provider_backend.yaml new file mode 100644 index 00000000..192db6bb --- /dev/null +++ b/iac-template/terraform-hcl-standard/aws-cloud/config/provider_backend.yaml @@ -0,0 +1,60 @@ +defaults: + terraform_required_version: ">= 1.2" + aws_provider_version: "~> 5.92.0" + session_name: "TerraformDevSession" + +modules: + dev: + account: dev + backend: + key: "account/dev/core/terraform.tfstate" + + dev-alb: + account: dev + backend: + key: "account/dev/alb/terraform.tfstate" + + dev-ec2: + account: dev + backend: + key: "account/dev/ec2/terraform.tfstate" + + dev-kafka: + account: dev + backend: + key: "account/dev/kafka/terraform.tfstate" + + dev-landingzone: + account: dev + backend: + key: "bootstrap/dev-landingzone/terraform.tfstate" + + dev-nlb: + account: dev + backend: + key: "account/dev/nlb/terraform.tfstate" + + dev-object: + account: dev + backend: + key: "account/dev/s3/terraform.tfstate" + + dev-rds: + account: dev + backend: + key: "account/dev/rds/terraform.tfstate" + + dev-redis: + account: dev + backend: + key: "account/dev/redis/terraform.tfstate" + + dev-role: + account: dev + backend: + key: "account/dev/iam/terraform.tfstate" + + dev-vpc: + account: dev + backend: + key: "account/dev/vpc/terraform.tfstate" diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/backend.tf deleted file mode 100644 index 4296bc50..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/backend.tf +++ /dev/null @@ -1,8 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/alb/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-alb/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/Makefile b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/Makefile index 6eff326a..fab1f518 100644 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/Makefile +++ b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/Makefile @@ -1,5 +1,8 @@ # envs/dev-ec2/Makefile +render: + python ../../render_provider_backend.py + init: terraform init --upgrade diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/backend.tf deleted file mode 100644 index 4f289d12..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/backend.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/ec2/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-ec2/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/Makefile b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/Makefile index d38e51f6..a1d4632f 100644 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/Makefile +++ b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/Makefile @@ -1,3 +1,6 @@ +render: + python ../../render_provider_backend.py + init: terraform init --upgrade diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/backend.tf deleted file mode 100644 index 98774a2a..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/backend.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/kafka/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-kafka/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/Makefile b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/Makefile index 2e9bcab5..a1d4632f 100644 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/Makefile +++ b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/Makefile @@ -1,9 +1,15 @@ +render: + python ../../render_provider_backend.py + init: terraform init --upgrade + plan: terraform plan + apply: terraform apply -auto-approve + destroy: terraform destroy -auto-approve diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/backend.tf deleted file mode 100644 index 3f1f8fc5..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/backend.tf +++ /dev/null @@ -1,8 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "bootstrap/dev-landingzone/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-landingzone/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/backend.tf deleted file mode 100644 index 0c74e7a4..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/backend.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/nlb/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-nlb/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/Makefile b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/Makefile index 0b047ac2..a1d4632f 100644 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/Makefile +++ b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/Makefile @@ -1,3 +1,6 @@ +render: + python ../../render_provider_backend.py + init: terraform init --upgrade @@ -9,3 +12,4 @@ apply: destroy: terraform destroy -auto-approve + diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/backend.tf deleted file mode 100644 index 87be4593..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/backend.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/s3/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-object/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/Makefile b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/Makefile index 3a2cd3d5..b16ffc00 100644 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/Makefile +++ b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/Makefile @@ -1,8 +1,10 @@ - SHELL := /bin/bash TF=terraform +render: + python ../../render_provider_backend.py + init: $(TF) init --upgrade diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-rds/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/backend.tf deleted file mode 100644 index aad095bf..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/backend.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/iam/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-redis/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/Makefile b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/Makefile index 7324b2e5..b16ffc00 100644 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/Makefile +++ b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/Makefile @@ -2,6 +2,9 @@ SHELL := /bin/bash TF=terraform +render: + python ../../render_provider_backend.py + init: $(TF) init --upgrade diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/backend.tf deleted file mode 100644 index aad095bf..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/backend.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/iam/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-role/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/Makefile b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/Makefile index 7324b2e5..b16ffc00 100644 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/Makefile +++ b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/Makefile @@ -2,6 +2,9 @@ SHELL := /bin/bash TF=terraform +render: + python ../../render_provider_backend.py + init: $(TF) init --upgrade diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/backend.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/backend.tf deleted file mode 100644 index 8bf36c42..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/backend.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "svc-plus-iac-state" - key = "account/dev/vpc/terraform.tfstate" - region = "ap-northeast-1" - dynamodb_table = "svc-plus-iac-state-dynamodb-lock" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/provider.tf b/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/provider.tf deleted file mode 100644 index 7bddf948..00000000 --- a/iac-template/terraform-hcl-standard/aws-cloud/envs/dev-vpc/provider.tf +++ /dev/null @@ -1,20 +0,0 @@ -terraform { - required_version = ">= 1.2" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.92.0" - } - } -} - -provider "aws" { - region = local.account.region - - assume_role { - role_arn = "arn:aws:iam::730335654753:role/TerraformDeployRole-Dev" - session_name = "TerraformDevSession" - } -} - diff --git a/iac-template/terraform-hcl-standard/aws-cloud/render_provider_backend.py b/iac-template/terraform-hcl-standard/aws-cloud/render_provider_backend.py new file mode 100644 index 00000000..bd56fd61 --- /dev/null +++ b/iac-template/terraform-hcl-standard/aws-cloud/render_provider_backend.py @@ -0,0 +1,107 @@ +from __future__ import annotations + +import os +import sys +from pathlib import Path +from typing import Dict + +from jinja2 import Environment, FileSystemLoader + +CURRENT_DIR = Path(__file__).resolve().parent +PROJECT_ROOT = CURRENT_DIR.parent +CONFIG_DIR = Path( + os.environ.get("AWS_CLOUD_CONFIG_PATH", PROJECT_ROOT / "aws-cloud" / "config") +) +TEMPLATE_DIR = CURRENT_DIR / "templates" +ENVS_DIR = CURRENT_DIR / "envs" + +sys.path.append(str(PROJECT_ROOT / "utils")) +from config_loader import load_merged_config # noqa: E402 + + +def build_provider_config(module_name: str, module_config: Dict, account_config: Dict, defaults: Dict) -> Dict: + region = module_config.get("region") or account_config.get("region") + if not region: + raise ValueError(f"Region is required for module {module_name}") + + return { + "terraform": { + "required_version": module_config.get("terraform_required_version") + or defaults.get("terraform_required_version", ">= 1.2"), + "aws_provider_version": module_config.get("aws_provider_version") + or defaults.get("aws_provider_version", "~> 5.92.0"), + }, + "region": region, + "assume_role_arn": module_config.get("assume_role_arn") + or account_config.get("role_to_assume"), + "session_name": module_config.get("session_name") + or defaults.get("session_name", "TerraformSession"), + } + + +def build_backend_config(module_name: str, module_config: Dict, account_config: Dict) -> Dict: + backend_overrides = module_config.get("backend", {}) + backend_bucket = backend_overrides.get("bucket") or account_config.get("backend", {}).get( + "bucket" + ) + dynamodb_table = backend_overrides.get("dynamodb_table") or account_config.get( + "backend", {} + ).get("dynamodb_table") + backend_key = backend_overrides.get("key") + backend_region = backend_overrides.get("region") or account_config.get("region") + + if not backend_bucket: + raise ValueError(f"Backend bucket is required for module {module_name}") + if not backend_key: + raise ValueError(f"Backend key is required for module {module_name}") + if not backend_region: + raise ValueError(f"Backend region is required for module {module_name}") + + return { + "bucket": backend_bucket, + "key": backend_key, + "region": backend_region, + "dynamodb_table": dynamodb_table, + } + + +def load_account_config(account_name: str, additional_inputs: list[str] | None = None) -> Dict: + account_config_path = CONFIG_DIR / "accounts" / f"{account_name}.yaml" + config_inputs = [str(account_config_path)] + [str(CONFIG_DIR / path) for path in additional_inputs or []] + return load_merged_config(config_inputs) + + +def render_templates(): + provider_backend_cfg = load_merged_config(CONFIG_DIR / "provider_backend.yaml") + defaults = provider_backend_cfg.get("defaults", {}) + modules = provider_backend_cfg.get("modules", {}) + + env = Environment(loader=FileSystemLoader(TEMPLATE_DIR), keep_trailing_newline=True) + provider_template = env.get_template("provider.tf.j2") + backend_template = env.get_template("backend.tf.j2") + + for module_name, module_config in modules.items(): + module_dir = ENVS_DIR / module_name + if not module_dir.exists(): + print(f"⚠️ Skipping {module_name}: {module_dir} not found") + continue + + account_name = module_config.get("account") + if not account_name: + raise ValueError(f"Account is required for module {module_name}") + + account_config = load_account_config(account_name, module_config.get("config_inputs")) + + provider_config = build_provider_config(module_name, module_config, account_config, defaults) + backend_config = build_backend_config(module_name, module_config, account_config) + + provider_content = provider_template.render(provider=provider_config) + backend_content = backend_template.render(backend=backend_config) + + (module_dir / "provider.tf").write_text(provider_content, encoding="utf-8") + (module_dir / "backend.tf").write_text(backend_content, encoding="utf-8") + print(f"✅ Rendered provider/backend for {module_name}") + + +if __name__ == "__main__": + render_templates() diff --git a/iac-template/terraform-hcl-standard/aws-cloud/templates/backend.tf.j2 b/iac-template/terraform-hcl-standard/aws-cloud/templates/backend.tf.j2 new file mode 100644 index 00000000..3b22a7ff --- /dev/null +++ b/iac-template/terraform-hcl-standard/aws-cloud/templates/backend.tf.j2 @@ -0,0 +1,8 @@ +terraform { + backend "s3" { + bucket = "{{ backend.bucket }}" + key = "{{ backend.key }}" + region = "{{ backend.region }}"{% if backend.dynamodb_table %} + dynamodb_table = "{{ backend.dynamodb_table }}"{% endif %} + } +} diff --git a/iac-template/terraform-hcl-standard/aws-cloud/templates/provider.tf.j2 b/iac-template/terraform-hcl-standard/aws-cloud/templates/provider.tf.j2 new file mode 100644 index 00000000..0638fc63 --- /dev/null +++ b/iac-template/terraform-hcl-standard/aws-cloud/templates/provider.tf.j2 @@ -0,0 +1,20 @@ +{% set terraform = provider.terraform %} +terraform { + required_version = "{{ terraform.required_version }}" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "{{ terraform.aws_provider_version }}" + } + } +} + +provider "aws" { + region = "{{ provider.region }}"{% if provider.assume_role_arn %} + assume_role { + role_arn = "{{ provider.assume_role_arn }}" + session_name = "{{ provider.session_name }}" + } +{% endif %} +} diff --git a/iac-template/terraform-hcl-standard/utils/__init__.py b/iac-template/terraform-hcl-standard/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/iac-template/terraform-hcl-standard/utils/config_loader.py b/iac-template/terraform-hcl-standard/utils/config_loader.py new file mode 100644 index 00000000..4e5ee2b7 --- /dev/null +++ b/iac-template/terraform-hcl-standard/utils/config_loader.py @@ -0,0 +1,86 @@ +from __future__ import annotations + +import os +from collections.abc import Mapping +from pathlib import Path +from typing import Iterable + +import yaml + +DEFAULT_IGNORE_FILES = {"vpn-keys.yaml"} + + +def deep_merge(dict1: dict, dict2: Mapping) -> dict: + """Recursively merge ``dict2`` into ``dict1`` and return a new dict.""" + result = dict1.copy() + for key, value in dict2.items(): + if key in result and isinstance(result[key], dict) and isinstance(value, Mapping): + result[key] = deep_merge(result[key], value) + elif key in result and isinstance(result[key], list) and isinstance(value, list): + result[key] = result[key] + value + else: + result[key] = value + return result + + +def _iter_yaml_files(path: Path, ignore_files: set[str]) -> Iterable[Path]: + if path.is_file(): + if path.suffix in {".yaml", ".yml"} and path.name not in ignore_files: + yield path + return + + patterns = ["**/*.yaml", "**/*.yml"] + seen: set[Path] = set() + for pattern in patterns: + for file_path in sorted(path.glob(pattern)): + if file_path.name in ignore_files or file_path in seen: + continue + seen.add(file_path) + yield file_path + + +def _normalize_inputs(config_inputs: list[str] | str | Path | None) -> list[str]: + if config_inputs is None: + env_paths = os.environ.get("CONFIG_PATHS") or os.environ.get("CONFIG_PATH") + config_inputs = env_paths.split(os.pathsep) if env_paths else ["config"] + + if isinstance(config_inputs, (Path, os.PathLike)): + config_inputs = [config_inputs] + + if isinstance(config_inputs, str): + config_inputs = [value for value in config_inputs.split(os.pathsep) if value] + + return [str(Path(path).expanduser()) for path in config_inputs] + + +def load_merged_config(config_inputs: list[str] | str | Path | None = None, ignore_files: list[str] | None = None) -> dict: + """ + Load and deep-merge YAML content from multiple files or directories. + + ``config_inputs`` accepts: + - A single path string or Path-like + - A list of path strings + - ``None`` (defaults to environment variable ``CONFIG_PATHS`` / ``CONFIG_PATH`` or ``config``) + """ + + ignore = DEFAULT_IGNORE_FILES | set(ignore_files or []) + merged: dict = {} + + resolved_inputs = _normalize_inputs(config_inputs) + if not resolved_inputs: + raise ValueError("No configuration inputs provided") + + loaded_paths: list[str] = [] + for raw_path in resolved_inputs: + path = Path(raw_path) + if not path.exists(): + raise FileNotFoundError(f"❌ 配置路径不存在: {path}") + + loaded_paths.append(str(path)) + for file_path in _iter_yaml_files(path, ignore): + with open(file_path, "r", encoding="utf-8") as handle: + content = yaml.safe_load(handle) or {} + merged = deep_merge(merged, content) + + merged["__config_paths__"] = loaded_paths + return merged