X回目の Terraform Repo ゼロからの作り直し
Sumary
Terraform のリポジトリをどうやって作り、どのようにチームで運用していくかという話題は、Terraformユーザーの中では数多く検討され、そのナレッジがWebで公開されています。
そんななかで幸運にも、もうすぐゼロから作る機会がありそうなので、いまのうちに最新の情報をキャッチアップしてお試し実装しようと思ってスクラップを作りました。
Policy
- Mono Repo & Multi Project
- Multiple Teams & Code Owners
- GitHub Actions as a dispacher
- 1 Environment 1 AWS Account
- Build at each AWS Account
Inspired By
Official
Important Practices
Others
- AWSアカウントとVPC、分ける? 分けない?: 分割パターンのメリット・デメリット | DevelopersIO
- shuaibiyy/awesome-terraform: Curated list of resources on HashiCorp's Terraform
Repository Structure
# tree
.
├── LICENSE
├── README.md
├── Taskfile.yml
├── docs
└── src
├── aws-cloudformation
│ └── tfstate
│ ├── README.md
│ ├── docs
│ ├── platform_1_cr
│ ├── platform_2_mn
│ ├── platform_3_di
│ ├── platform_4_jc
│ └── template
├── container
│ └── local-develop
│ ├── README.md
│ ├── cli
│ ├── docker-compose.yml
│ └── docs
├── helpers
│ ├── execute_terraform
│ │ ├── Runbook.md
│ │ ├── docs
│ │ └── main.sh
│ └── put_datadog_api_creds
│ ├── Runbook.md
│ ├── docs
│ └── main.sh
└── terraform
├── Runbook.md
├── tfs
├── examples
│ ├── aws-org-baseline
│ └── aws-release-terraform
├── modules # Cross Project Module
│ ├── README.md
│ ├── aws
│ └── datadog
└── platforms
├── platform_1_mn
├── platform_2_jm
├── platform_3_di
├── platform_4_gh
└── platform_5_af
├── environments
│ └── production
│ └── setup
│ ├── backend.tf
│ ├── main.tf
│ ├── providers.tf
│ └── terraform.tfvars
└── modules # In Project Module
└── service-name
├── README.md
├── main.tf
├── output.tf
├── required.tf
└── variables.tf
環境戦略とBranch戦略
デフォルトのブランチ戦略を使用する
デフォルトでは、Terraform コードを含むすべてのリポジトリで次の戦略を使用します。main ブランチはプライマリ開発ブランチであり、承認された最新のコードを表します。main ブランチは保護されています。
開発は、main ブランチから分岐する機能ブランチとバグ修正ブランチで行う。
機能ブランチ feature/$feature_name に名前を付ける。
バグ修正ブランチ fix/$bugfix_name に名前を付ける。
機能またはバグ修正が完了したら、そのブランチを pull リクエストで main ブランチにマージする。
マージの競合を防ぐには、マージする前にブランチをリベースします。
cf. https://cloud.google.com/docs/terraform/best-practices-for-terraform
ルート構成に環境ブランチを使用する
Google Cloud に直接デプロイされるルート構成を含むリポジトリには、安全なロールアウト戦略が必要です。環境ごとに別々のブランチを設定することをおすすめします。したがって、Terraform 構成の変更は、異なるブランチ間で変更をマージすることでプロモートできます。
cf. https://cloud.google.com/docs/terraform/best-practices-for-terraform
デフォルトじゃない方のパターンのイメージが付いてない。
terraform cli on docker container
Shellscript
Pull Request Template
GitHub Actions at Local
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ inputs.roleToAssume }}
aws-region: ap-northeast-1
role-duration-seconds: 3600
- name: Run CodeBuild
uses: aws-actions/aws-codebuild-run-build@v1
with:
project-name: ${{ inputs.codeBuildProjectName }}
env-vars-for-codebuild: |
custom,
requester,
event-name
env:
custom: my environment variable
requester: ${{ github.actor }}
event-name: ${{ github.event_name }}
terraform.backend
terraform {
backend "s3" {
profile = "default"
encrypt = "true"
lock_table = "terraform"
}
}
$ terraform init \
-backend-config="bucket=mybucket" \
-backend-config="key=mykey" \
-backend-config="region=us-east-1"
Terraform Provider / GitHub
CodeBuild & CodePipeline
wrapper script
'''sh
tfs plan|apply -tp target_product -e env_name -tl taeget_layer
'''