LoginSignup
24
20

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-12-21

概要

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側から簡単に見れるようにできたらと思います。

24
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
20