Merge pull request #146 from cloud-neutral-toolkit/codex/extract-public-config-to-yaml
Add shared bootstrap config and update workflow
This commit is contained in:
commit
bae23ad001
@ -12,16 +12,12 @@ on:
|
||||
inputs:
|
||||
deploy_action:
|
||||
type: choice
|
||||
options: [init, plan, apply, destroy]
|
||||
options: [plan, apply, destroy]
|
||||
default: plan
|
||||
deploy_dry_run:
|
||||
type: choice
|
||||
options: ['true', 'false']
|
||||
default: 'true'
|
||||
|
||||
env:
|
||||
TF_WORKDIR: iac-template/terraform-hcl-standard/aws-cloud
|
||||
DRY_RUN: ${{ github.event.inputs.deploy_dry_run || 'true' }}
|
||||
DEPLOY_ACTION: ${{ github.event.inputs.deploy_action || 'plan' }}
|
||||
|
||||
jobs:
|
||||
bootstrap:
|
||||
@ -51,33 +47,37 @@ jobs:
|
||||
run: make init
|
||||
|
||||
- name: Plan
|
||||
if: env.DRY_RUN == 'true'
|
||||
if: env.DEPLOY_ACTION == 'plan'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: make plan
|
||||
|
||||
- name: Apply
|
||||
if: env.DRY_RUN == 'false'
|
||||
if: env.DEPLOY_ACTION == 'apply'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: make apply
|
||||
|
||||
- name: Destroy
|
||||
if: env.DEPLOY_ACTION == 'destroy'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: make destroy
|
||||
|
||||
- name: Save Outputs
|
||||
if: env.DRY_RUN == 'false'
|
||||
if: env.DEPLOY_ACTION == 'apply'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: terraform output -json > ../../outputs_${{ matrix.target }}.json
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: env.DRY_RUN == 'false'
|
||||
if: env.DEPLOY_ACTION == 'apply'
|
||||
with:
|
||||
name: outputs-${{ matrix.target }}
|
||||
path: iac-template/terraform-standard/outputs_${{ matrix.target }}.json
|
||||
path: iac-template/terraform-hcl-standard/aws-cloud/outputs_${{ matrix.target }}.json
|
||||
|
||||
aggregate:
|
||||
name: "Aggregate Bootstrap Outputs"
|
||||
runs-on: ubuntu-latest
|
||||
needs: bootstrap
|
||||
|
||||
# ❗ Job-level 不能用 env.DRY_RUN,要用 github.event.inputs.*
|
||||
if: ${{ github.event.inputs.deploy_dry_run == 'false' }}
|
||||
if: ${{ github.event.inputs.deploy_action == 'apply' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
table_name ?=
|
||||
region ?=
|
||||
|
||||
TF_VARS := $(if $(table_name),-var="table_name=$(table_name)") $(if $(region),-var="region=$(region)")
|
||||
|
||||
init:
|
||||
terraform init --upgrade
|
||||
terraform init -migrate-state
|
||||
|
||||
apply: init
|
||||
terraform apply \
|
||||
-var="table_name=svc-plus-iac-state-dynamodb-lock" \
|
||||
-var="region=ap-northeast-1" \
|
||||
-auto-approve
|
||||
terraform apply $(TF_VARS) -auto-approve
|
||||
|
||||
plan: init
|
||||
terraform plan -var="table_name=svc-plus-iac-state-dynamodb-lock" -var="region=ap-northeast-1"
|
||||
terraform plan $(TF_VARS)
|
||||
|
||||
output: init
|
||||
terraform output
|
||||
destroy: init
|
||||
terraform destroy -var="table_name=svc-plus-iac-state-dynamodb-lock" -var="region=ap-northeast-1"
|
||||
|
||||
destroy: init
|
||||
terraform destroy $(TF_VARS)
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
locals {
|
||||
bootstrap = yamldecode(file("${path.root}/../config/accounts/bootstrap.yaml"))
|
||||
|
||||
dynamodb_table_name = coalesce(var.table_name, local.bootstrap.state.dynamodb_table_name)
|
||||
region = coalesce(var.region, local.bootstrap.region)
|
||||
environment = try(local.bootstrap.environment, "bootstrap")
|
||||
tags = try(local.bootstrap.tags, {})
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
resource "aws_dynamodb_table" "terraform_locks" {
|
||||
name = var.table_name
|
||||
name = local.dynamodb_table_name
|
||||
billing_mode = "PAY_PER_REQUEST"
|
||||
|
||||
hash_key = "LockID"
|
||||
@ -9,8 +9,11 @@ resource "aws_dynamodb_table" "terraform_locks" {
|
||||
type = "S"
|
||||
}
|
||||
|
||||
tags = {
|
||||
Name = var.table_name
|
||||
Environment = "bootstrap"
|
||||
}
|
||||
tags = merge(
|
||||
{
|
||||
Name = local.dynamodb_table_name
|
||||
Environment = local.environment
|
||||
},
|
||||
local.tags
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,5 +10,5 @@ terraform {
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.region
|
||||
region = local.region
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
variable "table_name" {
|
||||
description = "DynamoDB table name for Terraform state lock"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "AWS region"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
@ -1,29 +1,19 @@
|
||||
account_name ?= dev
|
||||
region ?= ap-northeast-1
|
||||
role_name ?= TerraformDeployRole-Dev
|
||||
terraform_user_name ?= sit-ci-runner
|
||||
account_name ?=
|
||||
region ?=
|
||||
role_name ?=
|
||||
terraform_user_name ?=
|
||||
|
||||
TF_VARS := $(if $(account_name),-var="account_name=$(account_name)") $(if $(region),-var="region=$(region)") $(if $(role_name),-var="role_name=$(role_name)") $(if $(terraform_user_name),-var="terraform_user_name=$(terraform_user_name)")
|
||||
|
||||
init:
|
||||
terraform init --upgrade
|
||||
terraform init -migrate-state
|
||||
apply: init
|
||||
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 apply -auto-approve $(TF_VARS)
|
||||
terraform output
|
||||
plan: init
|
||||
terraform plan \
|
||||
-var="account_name=$(account_name)" \
|
||||
-var="region=$(region)" \
|
||||
-var="role_name=$(role_name)" \
|
||||
-var="terraform_user_name=$(terraform_user_name)"
|
||||
terraform plan $(TF_VARS)
|
||||
output: init
|
||||
terraform output
|
||||
destroy: init
|
||||
terraform destroy \
|
||||
-var="account_name=$(account_name)" \
|
||||
-var="region=$(region)" \
|
||||
-var="role_name=$(role_name)" \
|
||||
-var="terraform_user_name=$(terraform_user_name)"
|
||||
terraform destroy $(TF_VARS)
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
locals {
|
||||
bootstrap = yamldecode(file("${path.root}/../config/accounts/bootstrap.yaml"))
|
||||
|
||||
config_account_name = coalesce(var.account_name, local.bootstrap.account_name)
|
||||
config_region = coalesce(var.region, local.bootstrap.region)
|
||||
config_role_name = coalesce(var.role_name, local.bootstrap.iam.role_name)
|
||||
config_terraform_user = coalesce(var.terraform_user_name, local.bootstrap.iam.terraform_user_name)
|
||||
environment = coalesce(try(local.bootstrap.environment, null), try(local.bootstrap.iam.environment, null), "bootstrap")
|
||||
extra_tags = try(local.bootstrap.tags, {})
|
||||
}
|
||||
|
||||
locals {
|
||||
account = yamldecode(
|
||||
file("${path.root}/../config/accounts/${local.config_account_name}.yaml")
|
||||
)
|
||||
}
|
||||
@ -1,21 +1,15 @@
|
||||
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
|
||||
name = local.config_role_name
|
||||
|
||||
assume_role_policy = jsonencode({
|
||||
Version = "2012-10-17"
|
||||
Statement = [{
|
||||
Effect = "Allow"
|
||||
Principal = {
|
||||
AWS = "arn:aws:iam::${local.account.account_id}:user/${var.terraform_user_name}"
|
||||
AWS = "arn:aws:iam::${local.account.account_id}:user/${local.config_terraform_user}"
|
||||
}
|
||||
Action = "sts:AssumeRole"
|
||||
}]
|
||||
@ -23,10 +17,11 @@ resource "aws_iam_role" "terraform_deploy_role" {
|
||||
|
||||
tags = merge(
|
||||
{
|
||||
Name = var.role_name
|
||||
Environment = local.account.environment
|
||||
Name = local.config_role_name
|
||||
Environment = coalesce(try(local.account.environment, null), local.environment)
|
||||
},
|
||||
local.account.tags
|
||||
try(local.account.tags, {}),
|
||||
local.extra_tags
|
||||
)
|
||||
}
|
||||
|
||||
@ -41,14 +36,14 @@ resource "aws_iam_role_policy_attachment" "attach_admin" {
|
||||
# IAM User for Terraform (AK/SK)
|
||||
# ----------------------------------------
|
||||
resource "aws_iam_user" "terraform_user" {
|
||||
name = var.terraform_user_name
|
||||
name = local.config_terraform_user
|
||||
}
|
||||
|
||||
#
|
||||
# IAM User Policy: 最小权限
|
||||
# ----------------------------------------
|
||||
resource "aws_iam_user_policy" "terraform_user_policy" {
|
||||
name = "${var.terraform_user_name}-iac-policy"
|
||||
name = "${local.config_terraform_user}-iac-policy"
|
||||
user = aws_iam_user.terraform_user.name
|
||||
|
||||
policy = jsonencode({
|
||||
@ -69,7 +64,7 @@ resource "aws_iam_user_policy" "terraform_user_policy" {
|
||||
Action = [
|
||||
"s3:ListBucket"
|
||||
],
|
||||
Resource = "arn:aws:s3:::svc-plus-iac-state"
|
||||
Resource = "arn:aws:s3:::${local.bootstrap.state.bucket_name}"
|
||||
},
|
||||
{
|
||||
Effect = "Allow",
|
||||
@ -78,7 +73,7 @@ resource "aws_iam_user_policy" "terraform_user_policy" {
|
||||
"s3:PutObject",
|
||||
"s3:DeleteObject"
|
||||
],
|
||||
Resource = "arn:aws:s3:::svc-plus-iac-state/*"
|
||||
Resource = "arn:aws:s3:::${local.bootstrap.state.bucket_name}/*"
|
||||
},
|
||||
|
||||
# DynamoDB: state lock table
|
||||
@ -91,7 +86,7 @@ resource "aws_iam_user_policy" "terraform_user_policy" {
|
||||
"dynamodb:UpdateItem",
|
||||
"dynamodb:DescribeTable"
|
||||
],
|
||||
Resource = "arn:aws:dynamodb:${var.region}:${local.account.account_id}:table/svc-plus-iac-state-dynamodb-lock"
|
||||
Resource = "arn:aws:dynamodb:${local.config_region}:${local.account.account_id}:table/${local.bootstrap.state.dynamodb_table_name}"
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@ -10,5 +10,5 @@ terraform {
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.region
|
||||
region = local.config_region
|
||||
}
|
||||
|
||||
@ -1,19 +1,23 @@
|
||||
variable "region" {
|
||||
description = "AWS region"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "account_name" {
|
||||
type = string
|
||||
description = "Which account configuration to load (e.g., dev)"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "role_name" {
|
||||
type = string
|
||||
description = "IAM role name to create (e.g., TerraformDeployRole-Dev)"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "terraform_user_name" {
|
||||
type = string
|
||||
description = "IAM username for Terraform IAC runner"
|
||||
default = null
|
||||
}
|
||||
|
||||
@ -1,15 +1,21 @@
|
||||
bucket_name ?=
|
||||
region ?=
|
||||
|
||||
TF_VARS := $(if $(bucket_name),-var="bucket_name=$(bucket_name)") $(if $(region),-var="region=$(region)")
|
||||
|
||||
init:
|
||||
terraform init --upgrade
|
||||
terraform init -migrate-state
|
||||
|
||||
apply: init
|
||||
terraform apply -var="bucket_name=svc-plus-iac-state" -var=region=ap-northeast-1 -auto-approve
|
||||
terraform apply $(TF_VARS) -auto-approve
|
||||
terraform output
|
||||
|
||||
plan: init
|
||||
terraform plan -var="bucket_name=svc-plus-iac-state" -var=region=ap-northeast-1
|
||||
terraform plan $(TF_VARS)
|
||||
|
||||
output: init
|
||||
terraform output
|
||||
|
||||
destroy: init
|
||||
terraform destroy -var="bucket_name=svc-plus-iac-state" -var=region=ap-northeast-1
|
||||
terraform destroy $(TF_VARS)
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
locals {
|
||||
bootstrap = yamldecode(file("${path.root}/../config/accounts/bootstrap.yaml"))
|
||||
|
||||
bucket_name = coalesce(var.bucket_name, local.bootstrap.state.bucket_name)
|
||||
region = coalesce(var.region, local.bootstrap.region)
|
||||
environment = try(local.bootstrap.environment, "bootstrap")
|
||||
tags = try(local.bootstrap.tags, {})
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
resource "aws_s3_bucket" "state" {
|
||||
bucket = var.bucket_name
|
||||
bucket = local.bucket_name
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_versioning" "versioning" {
|
||||
@ -19,3 +19,15 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "sse" {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_tagging" "default" {
|
||||
bucket = aws_s3_bucket.state.id
|
||||
|
||||
tag_set = [for k, v in merge({
|
||||
Name = local.bucket_name
|
||||
Environment = local.environment
|
||||
}, local.tags) : {
|
||||
key = k
|
||||
value = v
|
||||
}]
|
||||
}
|
||||
|
||||
@ -10,5 +10,5 @@ terraform {
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.region
|
||||
region = local.region
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
variable "bucket_name" {
|
||||
description = "S3 bucket name for Terraform state"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "AWS region"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
region: ap-northeast-1
|
||||
environment: bootstrap
|
||||
|
||||
account_name: dev
|
||||
|
||||
state:
|
||||
bucket_name: svc-plus-iac-state
|
||||
dynamodb_table_name: svc-plus-iac-state-dynamodb-lock
|
||||
|
||||
iam:
|
||||
role_name: TerraformDeployRole-Dev
|
||||
terraform_user_name: sit-ci-runner
|
||||
|
||||
tags:
|
||||
Owner: Platform
|
||||
Project: modern-container-app
|
||||
Loading…
Reference in New Issue
Block a user