CircleCIとTerraformでアカウント管理のコード化とデプロイ自動化

CircleCIとTerraformでアカウント管理のコード化とデプロイ自動化:


概要

TerraformのプロジェクトをCI/CDする情報があまりなかったので、アカウント管理用のプロジェクトを題材に試してみました。

管理対象のアカウントはAWSのIAMユーザーとGitHub Organizationのメンバーです。


AWSの準備


Terraform実行ユーザの作成

Terraformを実行するIAMユーザーを作成し、適切なIAMポリシーを割り当てます。

権限の範囲を気にしないのであれば、公式のIAMFullAccessとS3FullAccessのポリシーを割り当てれば十分です。ユーザー作成後はアクセスキー(アクセスキーIDとシークレットアクセスキー)を発行しておきます。


tfstateを保存するS3バケットの作成

CircleCI上でTerraformを動かす場合、tfstateを永続化する必要があります。

今回はS3にtfstateを保存し、実行時に共有する構成にします。

このtfstateを読み書きするために上記のS3FullAccessのポリシーが必要になります。


GitHubの準備

GitHubの準備はメンバーの追加削除ができる権限を持つPersonal Access Tokenを発行しておきます。

権限はadmin:orgのフルコントロールが必要になります。
スクリーンショット 2018-12-22 2.41.17.png


アカウント管理のTerraform化

variables.tfに変数を、main.tfに構成の定義を記載します。

実際の運用ではAWSのIAMユーザーは追加削除だけでなく、IAMポリシーの付与やグループへの追加も行うのでもう少し複雑になります。

variables.tf
# IAMユーザ一覧 
variable "iam_users" { 
  type = "list" 
  default = [ 
    "iam_user1", 
    "iam_user2", 
    "iam_user3", 
  ] 
} 
 
# GitHub Organizationのメンバー一覧 
variable "github_members" { 
  type = "list" 
  default = [ 
    "github_account1", 
    "github_account2", 
    "github_account3", 
  ] 
} 
main.tf
# tfstateの設定 
terraform { 
  backend "s3" { 
    encrypt = "true" 
    region = "ap-northeast-1" 
    bucket = "yukihira1992-tfstates" 
    key = "account-management/terraform.tfstate" 
    acl = "bucket-owner-full-control" 
  } 
} 
 
# AWS Providerの設定 
provider "aws" { 
  region = "ap-northeast-1" 
} 
 
# IAMユーザの設定 
resource "aws_iam_user" "iam_users" { 
  count = "${length(var.iam_users)}" 
  name = "${element(var.iam_users, count.index)}" 
  path = "/" 
  force_destroy = false 
} 
 
# GitHub Providerの設定 
provider "github" { 
  organization = "your_organizaion" 
} 
 
# GitHub Organizationのメンバー設定 
resource "github_membership" "this" { 
  count = "${length(var.github_members)}" 
  username = "${element(var.github_members, count.index)}" 
  role = "member" 
} 


CircleCIの設定


設定ファイルの作成

config.yaml
version: 2 
jobs: 
  test: 
    working_directory: ~/account-management 
    docker: 
      - image: hashicorp/terraform:light 
    steps: 
      - checkout 
      - run: 
          name: Init terraform 
          command: terraform init ~/account-management 
      - run: 
          name: Validate terraform 
          command: terraform validate ~/account-management 
      - run: 
          name: Plan terraform 
          command: terraform plan ~/account-management 
  deploy: 
    working_directory: ~/account-management 
    docker: 
      - image: hashicorp/terraform:light 
    steps: 
      - checkout 
      - run: 
          name: Init terraform 
          command: terraform init ~/account-management 
      - run: 
          name: Apply terraform 
          command: terraform apply -auto-approve ~/account-management 
workflows: 
  version: 2 
  test-and-deploy: 
    jobs: 
      - test 
      - hold: 
          type: approval 
          requires: 
            - test 
          filters: 
            branches: 
              only: master 
      - deploy: 
          requires: 
            - hold 
          filters: 
            branches: 
              only: master 
設定ファイルのポイントは次のとおりです。


Docker Image

CircleCI公式のTerraform用Docker Imageは無いのでHashicorpが用意しているhashicorp/terraformを採用しています。


Terraformのテスト

簡単ではありますが、terraform validateによる構文エラーのチェックとterraform planによる実行計画の確認を持ってしてテストとしています。(実行計画は人間がチェックする必要があります。)


terraform applyの確認回避

terraform applyは反映前に人間による確認を必要としているため -auto-approve オプションで確認を回避しています。

$ terraform apply -auto-approve 


Pull Requestマージ前のテストとマージ後のデプロイ

testジョブはすべてのブランチで実行されるため、testジョブの結果をPull Requestマージの条件にすることができます。

一方でdeployジョブはmasterブランチに限定しているため、Pull Requestがmasterブランチにマージされた後でのみ実行されます。また、deployジョブの前にholdジョブで処理を止め人間の確認を待ちます。


アクセス権限の設定

CircleCI上でAWSのAPIとGitHubのAPIを操作できるようアクセス権限を設定します。

アクセス権限はCircleCIのプロジェクトに環境変数として設定します。

必要な環境変数は次の4つになります。

  • AWS_DEFAULT_REGION : AWSのリージョン
  • AWS_ACCESS_KEY_ID : Terraform用IAMユーザーのアクセスキーID
  • AWS_SECRET_ACCESS_KEY : Terraform用IAMユーザーのシークレットアクセスキー
  • GITHUB_TOKEN : GitHub OrganizationのPersonal Access Token


ブランチ保護設定

GitHubの場合になりますが、Terraformリポジトリのmasterブランチの保護設定を有効にします。マージ前のチェックの設定を次のように設定します。test-and-deployは一度CircleCI上でWorkflowを動かすと選択できるようになります。


スクリーンショット 2018-12-22 3.37.34.png



動作確認

新しいブランチをGitHubにpushするとtestジョブが単独で実行されます。


スクリーンショット 2018-12-22 3.45.54.png


続いてPull Requestをmasterブランチにマージするとtest-and-deplyのすべてのジョブが実行され、holdジョブで確認待ちになります。


スクリーンショット 2018-12-22 3.47.42.png


holdジョブをクリックすると許可の確認をされるのでApproveをクリックします。


スクリーンショット 2018-12-22 3.48.00.png


最後に人間がholdジョブを承認するとdeployジョブが動き構成変更が反映されます。


スクリーンショット 2018-12-22 3.48.19.png



まとめ

アカウント管理をTerraformで行いCI/CDを組み合わせることでテストとデプロイを自動化してみました。

Terraformのような構成管理ツールにCI/CDを導入すると機密情報はCIサービスにのみ設定すればよく、個々の開発者が機密情報を保持する必要がなくなるのは大きなメリットだと思いました。次はTerraform planやapplyの結果をGitHub側から簡単に見れるようにできたらと思います。

コメント

このブログの人気の投稿

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-04-30 23:37:32 RSSフィード2021-04-30 23:00 分まとめ(42件)

投稿時間:2023-02-05 02:09:04 RSSフィード2023-02-05 02:00 分まとめ(9件)