refactor(iac): standardize terraform modules and pipelines across clouds

This commit is contained in:
Haitao Pan 2025-12-24 12:24:49 +08:00
parent 13ef638eac
commit 3e9995d5f3
64 changed files with 297 additions and 397 deletions

View File

@ -32,7 +32,7 @@ jobs:
echo "🔍 Checking workflow: $WF"
RUN=$(gh api \
repos/$REPO/actions/workflows/$WF/runs \
"repos/$REPO/actions/workflows/$WF/runs" \
-F branch="$BRANCH" \
-F per_page=1 \
--jq '.workflow_runs[0]')

View File

@ -4,9 +4,9 @@ on:
push:
pull_request:
paths:
- '.github/workflows/iac-pipeline-aws-account-matrix.yaml'
- 'terraform-hcl-standard/aws-cloud/component/vpc/**'
- 'terraform-hcl-standard/aws-cloud/component/role/**'
- '.github/workflows/iac-pipeline-aws-account-matrix.yaml'
workflow_dispatch:
inputs:
deploy_action:
@ -21,9 +21,10 @@ permissions:
env:
BASE_DIR: terraform-hcl-standard/aws-cloud/component/
DEPLOY_ACTION: ${{ github.event.inputs.deploy_action || 'plan' }}
CONFIG_DIR: gitops/xzerolab/sit/aws-cloud
CONFIG_FILES: |
config/xzerolab/sit/aws-cloud/account/accounts.yaml
config/xzerolab/sit/aws-cloud/resources/vpc.yaml
gitops/xzerolab/sit/aws-cloud/account/bootstrap.yaml
gitops/xzerolab/sit/aws-cloud/resources/vpc.yaml
jobs:
terraform:
@ -40,6 +41,12 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Checkout GitOps config
uses: actions/checkout@v4
with:
repository: cloud-neutral-workshop/gitops
path: gitops
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.9.5
@ -51,22 +58,23 @@ jobs:
- name: Load AWS config
run: |
ACCOUNT_FILE=$(printf "%s\n" "${CONFIG_FILES}" | head -n 1)
export ACCOUNT_FILE
python - <<'PY'
import os
import sys
from pathlib import Path
import os
import sys
from pathlib import Path
utils_dir = Path("terraform-hcl-standard/utils").resolve()
sys.path.insert(0, str(utils_dir))
utils_dir = Path("iac-template/terraform-hcl-standard/utils").resolve()
sys.path.insert(0, str(utils_dir))
from config_loader import load_account_credentials
from config_loader import load_account_credentials
region, role_arn = load_account_credentials(os.environ["ACCOUNT_FILE"])
region, role_arn = load_account_credentials(os.environ["ACCOUNT_FILE"])
with Path(os.environ["GITHUB_ENV"]).open("a", encoding="utf-8") as handle:
handle.write(f"AWS_REGION={region}\n")
handle.write(f"AWS_ROLE_ARN={role_arn}\n")
PY
with Path(os.environ["GITHUB_ENV"]).open("a", encoding="utf-8") as handle:
handle.write(f"AWS_REGION={region}\n")
handle.write(f"AWS_ROLE_ARN={role_arn}\n")
PY
- uses: aws-actions/configure-aws-credentials@v4
with:
@ -75,21 +83,21 @@ PY
- name: Init
working-directory: ${{ env.BASE_DIR }}/${{ matrix.component }}
run: make init
run: make init CONFIG_DIR=${{ env.CONFIG_DIR }}
- name: Plan
working-directory: ${{ env.BASE_DIR }}/${{ matrix.component }}
run: make plan
run: make plan CONFIG_DIR=${{ env.CONFIG_DIR }}
- name: Apply
working-directory: ${{ env.BASE_DIR }}/${{ matrix.component }}
if: ${{ env.DEPLOY_ACTION == 'apply' }}
run: make apply
run: make apply CONFIG_DIR=${{ env.CONFIG_DIR }}
- name: Destroy
working-directory: ${{ env.BASE_DIR }}/${{ matrix.component }}
if: ${{ env.DEPLOY_ACTION == 'destroy' }}
run: make destroy
run: make destroy CONFIG_DIR=${{ env.CONFIG_DIR }}
- name: Skip Apply/Destroy
if: ${{ env.DEPLOY_ACTION != 'apply' && env.DEPLOY_ACTION != 'destroy' }}

View File

@ -3,11 +3,10 @@ name: AWS Cloud Global LandingZone Baseline
on:
push:
pull_request:
paths:
paths:
- 'terraform-hcl-standard/aws-cloud/**'
- 'iac-template/terraform-hcl-standard/aws-cloud/**'
- '.github/workflows/iac-pipeline-aws-global-landingzone-baseline.yaml'
pull_request:
branches: [main]
workflow_dispatch:
inputs:

View File

@ -3,7 +3,6 @@ name: AWS Cloud IAC Pipeline (Resources Matrix)
on:
push:
pull_request:
paths:
paths:
- '.github/workflows/iac-pipeline-aws-resources-matrix.yaml'
- 'terraform-hcl-standard/aws-cloud/component/ec2/**'

View File

@ -42,11 +42,13 @@ jobs:
- name: Export Alicloud credentials
run: |
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}" >> "$GITHUB_ENV"
echo "TF_VAR_rds_password=${{ secrets.ALICLOUD_RDS_PASSWORD }}" >> "$GITHUB_ENV"
echo "TF_VAR_redis_password=${{ secrets.ALICLOUD_REDIS_PASSWORD }}" >> "$GITHUB_ENV"
{
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}"
echo "TF_VAR_rds_password=${{ secrets.ALICLOUD_RDS_PASSWORD }}"
echo "TF_VAR_redis_password=${{ secrets.ALICLOUD_REDIS_PASSWORD }}"
} >> "$GITHUB_ENV"
- name: Init
run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} init -upgrade

View File

@ -51,11 +51,13 @@ jobs:
- name: Export Alicloud credentials and variables
run: |
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}" >> "$GITHUB_ENV"
echo "TF_VAR_state_bucket=${{ secrets.ALICLOUD_STATE_BUCKET }}" >> "$GITHUB_ENV"
echo "TF_VAR_account_id=${{ secrets.ALICLOUD_ACCOUNT_ID }}" >> "$GITHUB_ENV"
{
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}"
echo "TF_VAR_state_bucket=${{ secrets.ALICLOUD_STATE_BUCKET }}"
echo "TF_VAR_account_id=${{ secrets.ALICLOUD_ACCOUNT_ID }}"
} >> "$GITHUB_ENV"
- name: Terraform Init
run: terraform -chdir=${{ env.TF_WORKDIR }}/${{ matrix.target }} init -upgrade
@ -101,9 +103,10 @@ jobs:
echo "{" > final_bootstrap_outputs.json
f=true
for x in outputs/**/outputs_*.json; do
k=$(basename $x .json | sed 's/outputs_//')
k=$(basename "$x" .json | sed 's/outputs_//')
value=$(cat "$x")
[ "$f" = true ] && f=false || echo "," >> final_bootstrap_outputs.json
echo "\"$k\": $(cat $x)" >> final_bootstrap_outputs.json
echo "\"$k\": $value" >> final_bootstrap_outputs.json
done
echo "}" >> final_bootstrap_outputs.json

View File

@ -39,11 +39,13 @@ jobs:
- name: Export Alicloud credentials
run: |
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}" >> "$GITHUB_ENV"
echo "TF_VAR_rds_password=${{ secrets.ALICLOUD_RDS_PASSWORD }}" >> "$GITHUB_ENV"
echo "TF_VAR_redis_password=${{ secrets.ALICLOUD_REDIS_PASSWORD }}" >> "$GITHUB_ENV"
{
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}"
echo "TF_VAR_rds_password=${{ secrets.ALICLOUD_RDS_PASSWORD }}"
echo "TF_VAR_redis_password=${{ secrets.ALICLOUD_REDIS_PASSWORD }}"
} >> "$GITHUB_ENV"
- name: Terraform Init (LandingZone)
working-directory: ${{ env.TF_WORKDIR }}/envs/dev

View File

@ -41,11 +41,13 @@ jobs:
- name: Export Alicloud credentials
run: |
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}" >> "$GITHUB_ENV"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}" >> "$GITHUB_ENV"
echo "TF_VAR_rds_password=${{ secrets.ALICLOUD_RDS_PASSWORD }}" >> "$GITHUB_ENV"
echo "TF_VAR_redis_password=${{ secrets.ALICLOUD_REDIS_PASSWORD }}" >> "$GITHUB_ENV"
{
echo "ALICLOUD_ACCESS_KEY=${{ secrets.ALICLOUD_ACCESS_KEY }}"
echo "ALICLOUD_SECRET_KEY=${{ secrets.ALICLOUD_SECRET_KEY }}"
echo "ALICLOUD_REGION=${ALICLOUD_REGION:-cn-hangzhou}"
echo "TF_VAR_rds_password=${{ secrets.ALICLOUD_RDS_PASSWORD }}"
echo "TF_VAR_redis_password=${{ secrets.ALICLOUD_REDIS_PASSWORD }}"
} >> "$GITHUB_ENV"
- name: Init
run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} init -upgrade

View File

@ -135,9 +135,9 @@ jobs:
set -euo pipefail
if [ "$TARGET" = "bootstrap-gcs" ]; then
if gcloud storage buckets describe gs://${BOOTSTRAP_BUCKET_NAME} >/dev/null 2>&1; then
gcloud storage rm --recursive gs://${BOOTSTRAP_BUCKET_NAME} || true
gcloud storage buckets delete gs://${BOOTSTRAP_BUCKET_NAME} --quiet || true
if gcloud storage buckets describe "gs://${BOOTSTRAP_BUCKET_NAME}" >/dev/null 2>&1; then
gcloud storage rm --recursive "gs://${BOOTSTRAP_BUCKET_NAME}" || true
gcloud storage buckets delete "gs://${BOOTSTRAP_BUCKET_NAME}" --quiet || true
else
echo "Bucket gs://${BOOTSTRAP_BUCKET_NAME} does not exist; skipping deletion."
fi
@ -179,9 +179,10 @@ jobs:
echo "{" > final_bootstrap_outputs.json
f=true
for x in outputs/**/outputs_*.json; do
k=$(basename $x .json | sed 's/outputs_//')
k=$(basename "$x" .json | sed 's/outputs_//')
[ "$f" = true ] && f=false || echo "," >> final_bootstrap_outputs.json
echo "\"$k\": $(cat $x)" >> final_bootstrap_outputs.json
value=$(cat "$x")
echo "\"$k\": $value" >> final_bootstrap_outputs.json
done
echo "}" >> final_bootstrap_outputs.json

View File

@ -45,7 +45,7 @@ jobs:
run: echo "TF_WORKDIR=${TF_ROOT}/${{ matrix.target }}" >> "$GITHUB_ENV"
- name: Terraform Init
run: terraform -chdir=$TF_WORKDIR init
run: terraform -chdir="$TF_WORKDIR" init
- name: Terraform ${{ env.DEPLOY_ACTION }}
run: terraform -chdir=$TF_WORKDIR $DEPLOY_ACTION -input=false
run: terraform -chdir="$TF_WORKDIR" "$DEPLOY_ACTION" -input=false

View File

@ -38,14 +38,14 @@ jobs:
run: echo "TF_VAR_vultr_api_key=${{ secrets.VULTR_API_KEY }}" >> "$GITHUB_ENV"
- name: Terraform Init
run: terraform -chdir=$TF_ROOT init
run: terraform -chdir="$TF_ROOT" init
- name: Terraform ${{ env.DEPLOY_ACTION }}
run: terraform -chdir=$TF_ROOT $DEPLOY_ACTION -input=false
run: terraform -chdir="$TF_ROOT" "$DEPLOY_ACTION" -input=false
- name: Capture LandingZone outputs
if: env.DEPLOY_ACTION == 'apply'
run: terraform -chdir=$TF_ROOT output -json > landingzone-baseline-outputs.json
run: terraform -chdir="$TF_ROOT" output -json > landingzone-baseline-outputs.json
- name: Upload LandingZone outputs
if: env.DEPLOY_ACTION == 'apply'

View File

@ -53,17 +53,17 @@ jobs:
env:
TF_VAR_region: ${{ matrix.region }}
TF_VAR_instance_type: ${{ matrix.instance_type }}
run: terraform -chdir=$TF_WORKDIR init
run: terraform -chdir="$TF_WORKDIR" init
- name: Terraform ${{ env.DEPLOY_ACTION }}
env:
TF_VAR_region: ${{ matrix.region }}
TF_VAR_instance_type: ${{ matrix.instance_type }}
run: terraform -chdir=$TF_WORKDIR $DEPLOY_ACTION -input=false
run: terraform -chdir="$TF_WORKDIR" "$DEPLOY_ACTION" -input=false
- name: Capture resource outputs
if: env.DEPLOY_ACTION == 'apply'
run: terraform -chdir=$TF_WORKDIR output -json > vultr-resources-${{ matrix.environment }}-${{ matrix.region }}-${{ matrix.instance_type }}.json
run: terraform -chdir="$TF_WORKDIR" output -json > vultr-resources-${{ matrix.environment }}-${{ matrix.region }}-${{ matrix.instance_type }}.json
- name: Upload resource outputs
if: env.DEPLOY_ACTION == 'apply'

View File

@ -1,33 +0,0 @@
[defaults]
# ✅ 动态主机清单
inventory = scripts/dynamic_inventory.py
# ✅ 加密解密 Vault 使用的密码文件
vault_password_file = ~/.vault_password
# ✅ 执行与性能优化
timeout = 10
forks = 10
poll_interval = 10
transport = smart
# ✅ 提升事实收集效率
gathering = smart
# ✅ 输出格式优化
stdout_callback = skippy
# ✅ 安全与兼容性
host_key_checking = False
deprecation_warnings = False
# ✅ 指定 Python 解释器(推荐动态)
#ansible_python_interpreter=/usr/bin/python3 # ⚠️ 如使用不同主机建议在 inventory 里指定
interpreter_python = auto_silent
[inventory]
# ✅ 启用缓存(提升性能)
cache = yes
cache_plugin = ansible.builtin.jsonfile
cache_timeout = 300 # 默认缓存 5 分钟

View File

@ -15,6 +15,22 @@ Both modules can be run independently.
---
** Note: S3 bucket must be emptied before deletion. **
## Config Source of Truth (GitOps)
All AWS config YAML now lives in the external GitOps repo:
```
https://github.com/cloud-neutral-workshop/gitops.git
```
Clone it next to this repo (default path used in Terraform), or override with
`TF_VAR_config_root`:
```
git clone https://github.com/cloud-neutral-workshop/gitops.git ../gitops
export TF_VAR_config_root="$(cd ../gitops && pwd)"
```
## 1. AWS Credentials Setup
Terraform reads AWS credentials through the standard AWS credential chain. You may use either A or B.
@ -143,10 +159,10 @@ To remove bootstrap resources:
terraform destroy
Resource names (bucket, DynamoDB table, IAM role/user) are defined in config/accounts/bootstrap.yaml. When tearing down the S3 backend, empty the configured bucket with AWS CLI first:
Resource names (bucket, DynamoDB table, IAM role/user) are defined in the GitOps repo at `config/accounts/bootstrap.yaml`. When tearing down the S3 backend, empty the configured bucket with AWS CLI first:
```
aws s3 rb "s3://$(python -c "import yaml;print(yaml.safe_load(open('config/accounts/bootstrap.yaml'))['state']['bucket_name'])")" --force
aws s3 rb "s3://$(python -c "import os,yaml;root=os.environ.get('TF_VAR_config_root','../gitops');print(yaml.safe_load(open(f'{root}/config/accounts/bootstrap.yaml'))['state']['bucket_name'])")" --force
```
@ -161,4 +177,3 @@ Terraform 读取你的 Access Key
Terraform 使用临时凭证执行所有资源创建
AccessKey → STS → AssumeRole → 临时 Token → Terraform apply

View File

@ -21,7 +21,7 @@ Terragrunt `run-all` handles the ordering; no manual sequencing is required.
- **Data plane**: S3 bucket enforces AES256 SSE, public access block, and versioning. DynamoDB enables server-side encryption and PITR for forensic recovery.
- **Control plane**: IAM policies are externalized in `identity/policies/*.json` and rendered via `aws_iam_policy_document` to keep Terraform code lean and auditable.
- **Config source of truth**: `config/accounts/bootstrap.yaml` defines canonical names, regions, and tags. Terragrunt passes outputs between modules to avoid drift.
- **Config source of truth**: The GitOps repo (`https://github.com/cloud-neutral-workshop/gitops.git`) stores `config/accounts/bootstrap.yaml`, defining canonical names, regions, and tags. Terragrunt reads it via `GITOPS_REPO_ROOT` (defaults to `../gitops` relative to this repo).
## How to Run with Terragrunt

View File

@ -1,5 +1,10 @@
locals {
bootstrap = yamldecode(file(abspath(var.bootstrap_config_path)))
config_root = coalesce(var.config_root, abspath("${path.module}/../../../../../gitops"))
bootstrap_config_path = coalesce(
var.bootstrap_config_path,
"${local.config_root}/config/accounts/bootstrap.yaml"
)
bootstrap = yamldecode(file(local.bootstrap_config_path))
config_account_name = coalesce(var.account_name, local.bootstrap.account_name)
config_region = coalesce(var.region, local.bootstrap.region)
@ -15,7 +20,7 @@ locals {
}
locals {
account_file_path = "${path.module}/../../../config/accounts/${local.config_account_name}.yaml"
account_file_path = "${local.config_root}/config/accounts/${local.config_account_name}.yaml"
account = fileexists(local.account_file_path) ? yamldecode(file(local.account_file_path)) : {
account_id = local.bootstrap.account_id
environment = local.environment

View File

@ -10,6 +10,15 @@ terraform {
source = "${get_parent_terragrunt_dir()}/..//bootstrap/identity"
}
inputs = {
bootstrap_config_path = abspath("${get_parent_terragrunt_dir()}/../config/accounts/bootstrap.yaml")
locals {
gitops_repo_root = get_env(
"GITOPS_REPO_ROOT",
abspath("${get_parent_terragrunt_dir()}/../../../../../gitops")
)
config_root = "${local.gitops_repo_root}/config"
}
inputs = {
bootstrap_config_path = "${local.config_root}/accounts/bootstrap.yaml"
config_root = local.gitops_repo_root
}

View File

@ -77,7 +77,13 @@ variable "state_lock_table_name" {
variable "bootstrap_config_path" {
description = "Path to the bootstrap account configuration YAML"
type = string
default = "../../config/accounts/bootstrap.yaml"
default = null
}
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}
variable "managed_policy_arns" {

View File

@ -1,5 +1,11 @@
locals {
bootstrap = yamldecode(file(abspath(var.bootstrap_config_path)))
config_root = coalesce(var.config_root, abspath("${path.module}/../../../../../gitops"))
bootstrap_config_path = coalesce(
var.bootstrap_config_path,
"${local.config_root}/config/accounts/bootstrap.yaml"
)
bootstrap = yamldecode(file(local.bootstrap_config_path))
dynamodb_table_name = coalesce(var.table_name, local.bootstrap.state.dynamodb_table_name)
region = coalesce(var.region, local.bootstrap.region)

View File

@ -10,6 +10,15 @@ terraform {
source = "${get_parent_terragrunt_dir()}/..//bootstrap/lock"
}
inputs = {
bootstrap_config_path = abspath("${get_parent_terragrunt_dir()}/../config/accounts/bootstrap.yaml")
locals {
gitops_repo_root = get_env(
"GITOPS_REPO_ROOT",
abspath("${get_parent_terragrunt_dir()}/../../../../../gitops")
)
config_root = "${local.gitops_repo_root}/config"
}
inputs = {
bootstrap_config_path = "${local.config_root}/accounts/bootstrap.yaml"
config_root = local.gitops_repo_root
}

View File

@ -13,5 +13,11 @@ variable "region" {
variable "bootstrap_config_path" {
description = "Path to the bootstrap account configuration YAML"
type = string
default = "../../config/accounts/bootstrap.yaml"
default = null
}
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,5 +1,11 @@
locals {
bootstrap = yamldecode(file(abspath(var.bootstrap_config_path)))
config_root = coalesce(var.config_root, abspath("${path.module}/../../../../../gitops"))
bootstrap_config_path = coalesce(
var.bootstrap_config_path,
"${local.config_root}/config/accounts/bootstrap.yaml"
)
bootstrap = yamldecode(file(local.bootstrap_config_path))
bucket_name = coalesce(var.bucket_name, local.bootstrap.state.bucket_name)
region = coalesce(var.region, local.bootstrap.region)

View File

@ -6,6 +6,15 @@ terraform {
source = "${get_parent_terragrunt_dir()}/..//bootstrap/state"
}
inputs = {
bootstrap_config_path = abspath("${get_parent_terragrunt_dir()}/../config/accounts/bootstrap.yaml")
locals {
gitops_repo_root = get_env(
"GITOPS_REPO_ROOT",
abspath("${get_parent_terragrunt_dir()}/../../../../../gitops")
)
config_root = "${local.gitops_repo_root}/config"
}
inputs = {
bootstrap_config_path = "${local.config_root}/accounts/bootstrap.yaml"
config_root = local.gitops_repo_root
}

View File

@ -13,7 +13,13 @@ variable "region" {
variable "bootstrap_config_path" {
description = "Path to the bootstrap account configuration YAML"
type = string
default = "../../config/accounts/bootstrap.yaml"
default = null
}
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}
variable "create_bucket" {

View File

@ -1,10 +1,12 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(
file("${path.root}/../../config/accounts/dev.yaml")
file("${local.config_root}/config/accounts/dev.yaml")
)
alb_conf = yamldecode(
file("${path.root}/../../config/resources/dev-alb/alb.yaml")
file("${local.config_root}/config/resources/dev-alb/alb.yaml")
)
}

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,8 +1,12 @@
# instance/ec2/Makefile
CONFIG_ROOT ?= ../../../../../gitops
CONFIG_DIR ?= $(CONFIG_ROOT)/config
export TF_VAR_config_root ?= $(CONFIG_ROOT)
render:
python ../../../utils/render_provider_backend.py \
--config-dir ../../config \
--config-dir $(CONFIG_DIR) \
--template-dir ../../templates \
--component-dir .. \
--component ec2

View File

@ -1,6 +1,8 @@
locals {
account = yamldecode(file("${path.root}/../../config/accounts/dev.yaml"))
ec2_conf = yamldecode(file("${path.root}/../../config/resources/ec2/dev.yaml"))
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(file("${local.config_root}/config/accounts/dev.yaml"))
ec2_conf = yamldecode(file("${local.config_root}/config/resources/ec2/dev.yaml"))
}
module "ami_lookup" {

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,6 +1,10 @@
CONFIG_ROOT ?= ../../../../../gitops
CONFIG_DIR ?= $(CONFIG_ROOT)/config
export TF_VAR_config_root ?= $(CONFIG_ROOT)
render:
python ../../../utils/render_provider_backend.py \
--config-dir ../../config \
--config-dir $(CONFIG_DIR) \
--template-dir ../../templates \
--component-dir .. \
--component kafka

View File

@ -1,10 +1,12 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(
file("${path.root}/../../config/accounts/dev.yaml")
file("${local.config_root}/config/accounts/dev.yaml")
)
kafka_conf = yamldecode(
file("${path.root}/../../config/resources/dev-kafka/msk.yaml")
file("${local.config_root}/config/resources/dev-kafka/msk.yaml")
)
}

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,6 +1,10 @@
CONFIG_ROOT ?= ../../../../../gitops
CONFIG_DIR ?= $(CONFIG_ROOT)/config
export TF_VAR_config_root ?= $(CONFIG_ROOT)
render:
python ../../../utils/render_provider_backend.py \
--config-dir ../../config \
--config-dir $(CONFIG_DIR) \
--template-dir ../../templates \
--component-dir .. \
--component landingzone

View File

@ -1,6 +1,8 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(
file("${path.root}/../../config/accounts/dev-landingzone.yaml")
file("${local.config_root}/config/accounts/dev-landingzone.yaml")
)
}

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,10 +1,12 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(
file("${path.root}/../../config/accounts/dev.yaml")
file("${local.config_root}/config/accounts/dev.yaml")
)
nlb_conf = yamldecode(
file("${path.root}/../../config/resources/dev-nlb/nlb.yaml")
file("${local.config_root}/config/resources/dev-nlb/nlb.yaml")
)
}

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -2,9 +2,13 @@ SHELL := /bin/bash
TF=terraform
CONFIG_ROOT ?= ../../../../../gitops
CONFIG_DIR ?= $(CONFIG_ROOT)/config
export TF_VAR_config_root ?= $(CONFIG_ROOT)
render:
python ../../../utils/render_provider_backend.py \
--config-dir ../../config \
--config-dir $(CONFIG_DIR) \
--template-dir ../../templates \
--component-dir .. \
--component rds

View File

@ -1,11 +1,13 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(
file("${path.root}/../../config/accounts/dev.yaml")
file("${local.config_root}/config/accounts/dev.yaml")
)
rds_conf = yamldecode(
file("${path.root}/../../config/resources/dev-rds/rds.yaml")
file("${local.config_root}/config/resources/dev-rds/rds.yaml")
)
}
@ -33,4 +35,3 @@ module "rds" {
tags = merge(local.account.tags, local.rds_conf.tags)
}

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,6 +1,8 @@
locals {
account = yamldecode(file("${path.root}/../../config/accounts/dev.yaml"))
redis = yamldecode(file("${path.root}/../../config/resources/dev-redis/redis.yaml"))
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(file("${local.config_root}/config/accounts/dev.yaml"))
redis = yamldecode(file("${local.config_root}/config/resources/dev-redis/redis.yaml"))
}
module "redis" {
@ -14,4 +16,3 @@ module "redis" {
security_group_ids = local.redis.security_group_ids
tags = local.account.tags
}

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -3,6 +3,9 @@ SHELL := /bin/bash
TF=terraform
CONFIG_FILES ?=
CONFIG_ROOT ?= ../../../../../gitops
CONFIG_DIR ?= $(CONFIG_ROOT)/config
export TF_VAR_config_root ?= $(CONFIG_ROOT)
CONFIG_FILES_JSON := $(shell python - <<'PY'
import json
@ -17,8 +20,8 @@ PY)
CONFIG_FILES_ENV := $(if $(CONFIG_FILES_JSON),TF_VAR_config_files='$(CONFIG_FILES_JSON)')
render:
python ../../../utils/render_provider_backend.py \
--config-dir ../../config \
python ../../../utils/render_provider_backend.py \
--config-dir $(CONFIG_DIR) \
--template-dir ../../templates \
--component-dir .. \
--component role

View File

@ -1,6 +1,8 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
config_files = length(var.config_files) > 0 ? var.config_files : [
abspath("${path.root}/../../../../../config/xzerolab/sit/aws-cloud/account/accounts.yaml"),
"${local.config_root}/config/xzerolab/sit/aws-cloud/account/accounts.yaml",
]
account = yamldecode(

View File

@ -3,3 +3,9 @@ variable "config_files" {
type = list(string)
default = []
}
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,6 +1,10 @@
CONFIG_ROOT ?= ../../../../../gitops
CONFIG_DIR ?= $(CONFIG_ROOT)/config
export TF_VAR_config_root ?= $(CONFIG_ROOT)
render:
python ../../../utils/render_provider_backend.py \
--config-dir ../../config \
--config-dir $(CONFIG_DIR) \
--template-dir ../../templates \
--component-dir .. \
--component s3

View File

@ -1,10 +1,12 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
account = yamldecode(
file("${path.root}/../../config/accounts/dev.yaml")
file("${local.config_root}/config/accounts/dev.yaml")
)
s3_conf = yamldecode(
file("${path.root}/../../config/resources/dev-object/bucket.yaml")
file("${local.config_root}/config/resources/dev-object/bucket.yaml")
)
}
@ -15,4 +17,3 @@ module "s3" {
enable_versioning = local.s3_conf.enable_versioning
tags = local.account.tags
}

View File

@ -0,0 +1,5 @@
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,4 +1,7 @@
CONFIG_FILES ?=
CONFIG_ROOT ?= ../../../../../gitops
CONFIG_DIR ?= $(CONFIG_ROOT)/config
export TF_VAR_config_root ?= $(CONFIG_ROOT)
CONFIG_FILES_JSON := $(shell python - <<'PY'
import json
@ -13,11 +16,11 @@ PY)
CONFIG_FILES_ENV := $(if $(CONFIG_FILES_JSON),TF_VAR_config_files='$(CONFIG_FILES_JSON)')
render:
python ../../../utils/render_provider_backend.py \
--config-dir ../../config \
--template-dir ../../templates \
--component-dir .. \
--component vpc
python ../../../utils/render_provider_backend.py \
--config-dir $(CONFIG_DIR) \
--template-dir ../../templates \
--component-dir .. \
--component vpc
init: render
$(CONFIG_FILES_ENV) terraform init --upgrade

View File

@ -1,7 +1,9 @@
locals {
config_root = coalesce(var.config_root, abspath("${path.root}/../../../../../gitops"))
config_files = length(var.config_files) > 0 ? var.config_files : [
abspath("${path.root}/../../../../../config/xzerolab/sit/aws-cloud/account/accounts.yaml"),
abspath("${path.root}/../../../../../config/xzerolab/sit/aws-cloud/resources/vpc.yaml"),
"${local.config_root}/config/xzerolab/sit/aws-cloud/account/accounts.yaml",
"${local.config_root}/config/xzerolab/sit/aws-cloud/resources/vpc.yaml",
]
account = yamldecode(file(local.config_files[0]))

View File

@ -3,3 +3,9 @@ variable "config_files" {
type = list(string)
default = []
}
variable "config_root" {
description = "Local path to the gitops repository root."
type = string
default = null
}

View File

@ -1,17 +0,0 @@
region: ap-northeast-1
environment: bootstrap
account_name: xzerolab
account_id: 950604983695
state:
bucket_name: aws-cloud-iac-state
dynamodb_table_name: aws-cloud-iac-state-dynamodb-lock
iam:
role_name: IacDeployRole
terraform_user_name: github-ci-runner
tags:
Owner: Platform
Project: CloudNeutral

View File

@ -1,9 +0,0 @@
region: "ap-northeast-1"
account_id: "950604983695"
landingzone:
console_mode: "readonly" # 可选deny / readonly
enable_risp_controls: true # 限制 RI/SP 购买
enable_root_limited: true # 限制 root API
enable_mfa_enforce: true # 强制 MFA

View File

@ -1,19 +0,0 @@
account_id: 950604983695
name: dev
environment: dev
region: ap-northeast-1
role_to_assume: "arn:aws:iam::950604983695:role/IacDeployRole"
logging_bucket: org-dev-logs
shared_vpc_account: "950604983695" # 单账号,所以保持一致
tags:
Environment: dev
Owner: Platform
CostCenter: "DEV"
Project: CloudNeutral
backend:
bucket: aws-cloud-iac-state
dynamodb_table: aws-cloud-iac-state-dynamodb-lock

View File

@ -1,61 +0,0 @@
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
component_dir: s3
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"

View File

@ -1,19 +0,0 @@
name_prefix: "dev-alb"
vpc_id: "vpc-0d0d8d822fa215104"
subnet_ids:
- "subnet-0c370f7ff7311388e"
- "subnet-0b609b5773fe957fa"
listeners:
- port: 80
protocol: "HTTP"
target_group_port: 80
target_group_protocol: "HTTP"
- port: 443
protocol: "HTTPS"
certificate_arn: "arn:aws:acm:ap-northeast-1:xxxx:certificate/xxxx-xxxx"
target_group_port: 443
target_group_protocol: "HTTP"

View File

@ -1,16 +0,0 @@
name_prefix: "dev-kafka"
kafka_version: "3.6.0"
brokers:
instance_type: "kafka.t3.small"
number_of_broker_nodes: 2
ebs:
volume_size: 50
vpc_id: "vpc-0d0d8d822fa215104"
subnet_ids:
- "subnet-0c370f7ff7311388e"
- "subnet-0b609b5773fe957fa"

View File

@ -1,13 +0,0 @@
name_prefix: "dev-nlb"
vpc_id: "vpc-0d0d8d822fa215104"
subnet_ids:
- "subnet-0c370f7ff7311388e"
- "subnet-0b609b5773fe957fa"
listeners:
- port: 80
protocol: "TCP"
target_group_port: 80
target_group_protocol: "TCP"

View File

@ -1,10 +0,0 @@
bucket_name: "svc-plus-dev-objects"
# 是否开启版本管理(默认建议开启)
enable_versioning: true
# 是否启用加密,之后如果你想加 KMS 可以扩展
enable_encryption: false
# Public Access Block通常建议保持 true
block_public_access: true

View File

@ -1,33 +0,0 @@
name_prefix: "dev-rds"
engine: "postgres"
engine_version: "16.1"
instance_class: "db.t3.micro"
username: "admin"
password: "StrongPassword123"
allocated_storage: 20
max_allocated_storage: 100
multi_az: false
publicly_accessible: false
subnet_ids:
- "subnet-0996ad2f8e8f96445"
- "subnet-0eaa450d1bb6f65be"
vpc_security_group_ids:
- "sg-0ebfd69a09f87af4d"
parameters:
- name: "log_min_duration_statement"
value: "1000"
- name: "log_statement"
value: "ddl"
tags:
Environment: "dev"
Owner: "Platform"

View File

@ -1,13 +0,0 @@
name_prefix: "dev-redis"
engine_version: "7.0"
node_type: "cache.t3.micro"
num_cache_nodes: 1
subnet_ids:
- "subnet-xxxxxx"
- "subnet-yyyyyy"
security_group_ids:
- "sg-xxxxxx"

View File

@ -1,26 +0,0 @@
name_prefix: "dev-ec2"
vpc_id: "vpc-06e1d6dab47b1d35f"
subnet_id: "subnet-06859ec23046f4556"
instance:
type: "t3.micro"
ami: "ubuntu-2204"
keypair:
name: "dev-key"
public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDEsuS135lzjVvlH2iNrKz23lDFr7b686xs4d2HINP2glFPmgkgx1D6Dqwisb1UbhWHZmUUzRxXeNlE8fiaO0TXN/C0dsdUxgopnQRyakcA+gfJqqb38Syx8eqdC7mQy9ygOf763dWm6d/SYZ8WgNWLldk4QF9DiZOW9K22DMtY4/1Cqe/YE/WGpOMVr9T9BwvmOjarjWp2OPbx6RVlSOd735Mze5X+cJ9QqdLaisCiSoJ3j9S6dulcxm+7ghPfATvxlJyZWSrRrVqnmV45lPbeuUHlIEyuK1PK2MS6NtUP03ZhdRYJQKZLECpR5xAO/BliOtDdRornvHV1gutYD8/n3IS8sRVzYPvN9DuOhzBnBQUgciu2++R8zMfdVoH7mSbsE8u++vMcBk3UJ1Op0Ct+trl2bsnue96cAnoiII08JKwAaczD5uZIGhdkGV8zKnChNCjzCxP0i4PV/MYW04eWmH+E8G81zq4ZsvrvPYmilBbRrkwHvvbPba3SSb2F2As= shenlan@shenlandeMacBook-Air-2.local"
security_group:
name: "dev-ec2-sg"
ssh_cidr: "0.0.0.0/0"
additional_ingress:
- port: 80
protocol: tcp
cidr: "0.0.0.0/0"
- port: 443
protocol: tcp
cidr: "0.0.0.0/0"
- port: 1443
protocol: tcp
cidr: "0.0.0.0/0"

View File

@ -1,19 +0,0 @@
name_prefix: "dev-vpc"
vpc_cidr: "10.0.0.0/16"
public_subnets:
- cidr: "10.0.1.0/24"
az: "ap-northeast-1a"
name: "dev-public-1"
- cidr: "10.0.2.0/24"
az: "ap-northeast-1c"
name: "dev-public-2"
private_subnets:
- cidr: "10.0.11.0/24"
az: "ap-northeast-1a"
name: "dev-private-1"
- cidr: "10.0.12.0/24"
az: "ap-northeast-1c"
name: "dev-private-2"

View File

@ -16,8 +16,8 @@ for FILE in ${FILES}; do
# Point any lingering envs/dev-* references to the new instance layout
${SED_CMD} -i'' -e 's|envs/dev-[a-zA-Z0-9_-]*/|instance/|g' "${FILE}"
# Ensure YAML lookups target the config folder two levels up
${SED_CMD} -i'' -e 's|file("${path.root}/../../config/|file("${path.root}/../../config/|g' "${FILE}"
# Ensure YAML lookups target the centralized gitops config root
${SED_CMD} -i'' -e 's|file("${path.root}/../../config/|file("${local.config_root}/config/|g' "${FILE}"
# Keep module sources anchored on the shared modules directory
${SED_CMD} -i'' -e 's|source = "../../modules/|source = "../../modules/|g' "${FILE}"