前回ではDigitalOceanでのTerraform x CircleCIの実装をしましたが、今回はAWSで試してみました。今回は本番の他にStagingが増えただけなので、実装方法は基本変わらない作りとなっています。
■構成
- Repository
1 2 3 4 5 6 7 8 9 10 |
terraform ├── prd │ ├── backend.tf │ ├── route53-.tf ~省略~ └── stg ├── backend.tf ├── ecr.tf ├── ecs.tf ~省略~ |
- CI/CDフロー
- 流れ
- プルリクを出す
- stg/本番
terraform init
terraform fmt
,terraform validate
,terraform plan
- master マージ
- stg/本番
terraform init
terraform fmt
,terraform validate
,terraform plan
,terraform apply
■.circleci/config.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
version: 2.1 references: default_config: &default_config docker: - image: hashicorp/terraform:0.12.29 working_directory: ~/project environment: TERRAFORM_ENV: ~/project/ ## stg stg_set_terraform_environment: &stg_set_terraform_environment run: name: set terraform environment command: | mkdir -p ~/.aws echo "[stg-adachin-terraform]" > ~/.aws/credentials echo "aws_access_key_id = ${STG_TERRAFORM_AWS_ACCESS_KEY_ID}" >> ~/.aws/credentials echo "aws_secret_access_key = ${STG_TERRAFORM_AWS_SECRET_ACCESS_KEY}" >> ~/.aws/credentials echo "region = ap-northeast-1" >> ~/.aws/credentials stg_terraform_init: &stg_terraform_init run: name: terraform init command: | cd ~/project/terraform/stg terraform init ## Prd prd_set_terraform_environment: &prd_set_terraform_environment run: name: set terraform environment command: | mkdir -p ~/.aws echo "[prd-adachin-terraform]" > ~/.aws/credentials echo "aws_access_key_id = ${PRD_TERRAFORM_AWS_ACCESS_KEY_ID}" >> ~/.aws/credentials echo "aws_secret_access_key = ${PRD_TERRAFORM_AWS_SECRET_ACCESS_KEY}" >> ~/.aws/credentials echo "region = ap-northeast-1" >> ~/.aws/credentials prd_terraform_init: &prd_terraform_init run: name: terraform init command: | cd ~/project/terraform/prd terraform init jobs: stg_terraform_fmt_validate: <<: *default_config steps: - checkout - *stg_set_terraform_environment - *stg_terraform_init - run: name: terraform fmt validate command: | cd ~/project/terraform/stg terraform fmt -diff=true -check=true terraform validate prd_terraform_fmt_validate: <<: *default_config steps: - checkout - *prd_set_terraform_environment - *prd_terraform_init - run: name: terraform fmt validate command: | cd ~/project/terraform/prd terraform fmt -diff=true -check=true terraform validate stg_terraform_plan: <<: *default_config steps: - *stg_set_terraform_environment - *stg_terraform_init - run: name: terraform plan command: | cd ~/project/terraform/stg terraform plan prd_terraform_plan: <<: *default_config steps: - *prd_set_terraform_environment - *prd_terraform_init - run: name: terraform plan command: | cd ~/project/terraform/prd terraform plan stg_terraform_apply: <<: *default_config steps: - checkout - *stg_set_terraform_environment - *stg_terraform_init - run: name: terraform apply command: | cd ~/project/terraform/stg terraform apply -auto-approve prd_terraform_apply: <<: *default_config steps: - checkout - *prd_set_terraform_environment - *prd_terraform_init - run: name: terraform apply command: | cd ~/project/terraform/prd terraform apply -auto-approve workflows: version: 2 deploy: jobs: - stg_terraform_fmt_validate - stg_terraform_plan: requires: - stg_terraform_fmt_validate - stg_terraform_apply: filters: branches: only: master requires: - stg_terraform_plan - prd_terraform_fmt_validate - prd_terraform_plan: requires: - prd_terraform_fmt_validate - prd_terraform_apply: filters: branches: only: master requires: - prd_terraform_plan |
- Environment Variables
PRD_TERRAFORM_AWS_ACCESS_KEY_ID
PRD_TERRAFORM_AWS_SECRET_ACCESS_KEY
STG_TERRAFORM_AWS_ACCESS_KEY_ID
STG_TERRAFORM_AWS_SECRET_ACCESS_KEY
追加したのは環境ごとのクレデンシャルを読み込ませており、 Jobs
でprdとstgを分けています。それに毎回マージするたびに terraform apply
されてしまうので怖いのですが、基本planでエラーが出ていれば止まるので、制御文入れればもっと安全ですね。さらに改善する余地がありますな。あとterraformのコンテナイメージは hashicorp/terraform:light
にすると最新を持ってきてしまうのでバージョン固定にしています。
■Test push/merge
- fail
- push
- master merge
■まとめ
とりあえずザッーと作ってしまいましたが、実際に運用してみると課題がありそうですな。でも、terraformは頻繁にバージョンアップがあるし、CI回すことで冪等性も保たれるということがメリットになります。ちなみに terraform apply
してもエラーが出ることもありますが、Deployサーバーなどでエラーを解決してプルリクを出せば結局問題なく運用できると思います。運用し始めたけどplanまででいいかも。。
※追記
applyはpath-filteringで!
[CircleCI][Orbs][path-filtering]特定ディレクトリに差分が出たらterraform applyを適用するように実装してみた
0件のコメント