Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWS Codeシリーズを使った TerraformのCICDパイプラインの作り方

hiyanger
January 24, 2024

AWS Codeシリーズを使った TerraformのCICDパイプラインの作り方

2024/1/25
【サーバーワークス主催】クラウドエンジニア交流会【LT大会もあるぞ!】
https://serverworks.connpass.com/event/304983/

※反省メモ
・自己紹介に趣味、好きなアーティストいれてもいいかも
・構成図は終盤スライドがへったので合間合間にもうちょっと入れた方がよかった

hiyanger

January 24, 2024
Tweet

More Decks by hiyanger

Other Decks in Technology

Transcript

  1. もくじ 全体構成 商用環境 CodeBuild / CodePipeline IAMロール 商用環境 S3 /

    KMS 検証環境 CodeCommit IAMロール 商用環境 CodeBuild / CodePipeline 実際に運用して困ったこと ロール系もお仕事で運用することを 考えてしっかり全リソース許可とかは基本せず、 セキュアなポリシーを意識してます
  2. 【商用】CodeBuild / CodePipeline IAMロール ▪ CodeBuild / terraform plan  

    # AWS管理ポリシー   ・ReadOnlyAccess   # ユーザー管理ポリシー   ・ログ出力のためのCloudWatchの出力許可   ・アーティファクト/tfstate S3入出力の許可   ・terraformを動作させるECRの動作許可   ・terraform排他制御のためのDynamoDBの動作許可   ・APIキーを暗号化してる場合のDecrypt許可(必要なら) ▪ CodeBuild / terraform apply  # AWS管理ポリシー   ・IAMFullAccess   ・PowerUserAccess ▪ Codepipeline   # ユーザー管理ポリシー   ・検証CodeCommitへのAssumeRole   ・アーティファクトS3入出力の許可   ・CodeBuildの動作許可
  3. 【商用】アーティファクト S3 / KMS ▪ KMS  # AWS管理ポリシー   ・ルートユーザーへの全許可   ・管理ユーザーへのアクセス許可

      ・CodeBuild、CodePipeline、検証rootへの利用許可   ・CodeBuild、CodePipeline、検証rootへの一時許可 ▪ S3  # AWS管理ポリシー   ・バケット/ポリシー削除拒否   ・SSL以外のアクセス拒否   ・検証CodeCommitからのList/Get/Put許可  # ライフサイクルルール   ・30日で設定
  4. 【商用】CodeCommit IAMロール ▪ 信頼ポリシー data "aws_iam_policy_document" "codecommit_assume_role_policy" { statement {

    actions = ["sts:AssumeRole"] principals { type = "AWS" identifiers = ["arn:aws:iam::${var.account-prd}:root"] } } } ▪ AWS管理ポリシー   ・商用アーティファクトS3へのPut許可   ・商用アーティファクトS3/KMSへのアクセス許可   ・CodeCommitへのアクセス許可
  5. 【商用】CodeBuild(terraform plan/apply) resource "aws_codebuild_project" "codebuild-terraform-plan" { name = "${var.env}-codebuild-terraform-plan" service_role

    = module.common.codebuild-terraform-plan-role_arn encryption_key = "arn:aws:kms:ap-northeast-1:${var.account-id}:key/${var.prd-art ifact-terraform-kms-id}" artifacts { type = "CODEPIPELINE" } environment { compute_type = "BUILD_GENERAL1_SMALL" image = "public.ecr.aws/hashicorp/terraform:1.5.7" type = "LINUX_CONTAINER" environment_variable { name = "dir" value = var.env } } source { type = "CODEPIPELINE" buildspec = "buildspec_terraform_plan.yml" } } ※applyはplanを読み替えるだけでOK! ※AWSコンソールから設定できないので  CLIやterraformからデプロイや!
  6. 【商用】CodeBuild(buildspec) version: 0.2 phases: build: commands: - cd $dir -

    terraform init -input=false -no-color - terraform plan -input=false -no-color artifacts: files: - '**/*' version: 0.2 phases: build: commands: - cd $dir - terraform apply -input=false -auto-approve -no-color artifacts: files: - '**/*' buildspec_plan.yml buildspec_apply.yml
  7. 【商用】CodePipeline(Source) resource "aws_codepipeline" "codepipeline-terraform" { name = "${var.env}-codepipeline-terraform" role_arn =

    aws_iam_role.codepipeline-terraform-role.arn stage { name = "Source" action { name = "Source" category = "Source" owner = "AWS" provider = "CodeCommit" version = "1" output_artifacts = ["source_output"] role_arn = "arn:aws:iam::${var.account-dev}:role/stg-codecommit-terraform- role" configuration = { RepositoryName = "stg-codecommit-terraform" BranchName = "main" } } } ※Pipelineも同じくAWSコンソールから  設定できないのでCLIやterraformからデプロイや!
  8. 【商用】CodePipeline(plan / approval) stage { name = "Build-Plan" action {

    name = "terraform-plan" category = "Build" owner = "AWS" provider = "CodeBuild" input_artifacts = ["source_output"] output_artifacts = ["plan_output"] version = "1" configuration = { ProjectName = "${var.env}-codebuild-terraform-plan" } } } stage { name = "Approval" action { name = "plan-approval" category = "Approval" owner = "AWS" provider = "Manual" version = "1" } }
  9. 【商用】CodePipeline(apply / S3 / KMS) stage { name = "Build-Apply"

    action { name = "terraform-apply" category = "Build" owner = "AWS" provider = "CodeBuild" input_artifacts = ["plan_output"] version = "1" configuration = { ProjectName = "${var.env}-codebuild-terraform-apply" } } } artifact_store { location = aws_s3_bucket.artifact-terraform.id type = "S3" encryption_key { id = aws_kms_alias.artifact-terraform.arn type = "KMS" } } }
  10. 実際に運用して困ったこと × 改善が難しい デプロイは基本的にコードを経由する必要があるため、構築の瞬発力が落ちる IaCの特性上やむを得ない。どうしても急ぎなら手動とかで。 plan/applyでエラーが起こると構築が止まってしまう planはローカルで。applyまで検証したいなら別環境とかでやる。 手動変更やローカルから直applyされると、都度確認が必要になる テスト中はやむを得ない手動変更とかが起きる。 その間はパイプラインを止めておくなど、うまくスケジュールする。

    共通リソースがあるので、商用だけ一部先行着手とかが難しい developとmainは共通化されるので共通リソースも中途半端に デプロイされてしまう。先行してやるなら手動やローカルから流す。 ※チーム構成 全体4名(ガッツリ書く人2名、そこそこ書く人2名、Lambda等は別部隊で記述) ◯ 改善が可能 terraformを使えるメンバーが少なかったので、applyの依頼が集中 少なくともインフラチームはみんな使えた方がいい。 記述方法が個人間で差がでる 事前に軽い規約は作ったが、まだまだ弱かった。 開発同様、より強い規約の制定が必要。