AzureDevOpsパイプラインを使って、AWSマルチアカウントにTerraformをどう使うか

カバーイメージ

このセッションでは、Terraformを使ってAWSクラウドのマルチアカウントに対するインフラのプロビジョニングを行う方法について、クロスアカウントIAMロールとAzureDevOpsパイプラインを活用して自動デプロイをする方法を見ていきましょう。

以下のトピックに分けて説明していきます。

  1. アーキテクチャ図
  2. AWSマルチアカウント作成設定
  3. Terraformインフラコード
  4. デプロイ自動化のためのAzureDevOpsパイプラインコード

アーキテクチャ図

AWS, Terraform, Azure DevOps

上のアーキテクチャ図から、ワークフローをリストアップしましょう。

ワークフロー1

AWSマルチアカウントを作成する必要があります。この例では基本的に3つのアカウントです。下記のステップはAWSコンソールやAWS CLIコマンドで手動で作成する必要があります。

- 管理/DevOpsアカウント

  1. このアカウントで、IAMユーザー(例えば vscode といった自動化ユーザー)を管理し、このユーザーのアクセスIDとシークレットキーを生成します。それらはTerraformが使用します。

  2. ユーザー 'vscode' がDevelopmentやProductionの信頼するアカウントの役割を引き受けることができるように、最小特権ロールを割り当てます。 STSポリシーのみを添付してください。

- 開発アカウント

  1. 管理/DevOpsアカウントの信頼できるアカウントARNを指定して、例えば、Admin権限のManageInDevAsAdminロールを作成します。管理に必要な最小限の特権を持ったものです。

- 本番アカウント

  1. 管理/DevOpsアカウントの信頼できるアカウントARNを指定して、例えば、Admin権限のManageInProdAsAdminロールを作成します。管理に必要な最小限の特権を持ったものです。

これらのステップが完了すると、Terraform自動化は vscode の認証情報を使用して、異るAWSアカウントでリソースをプロビジョニングすることができます。

ワークフロー2、3

Azure DevOpsツールは、ソースコードリポジトリの管理、デプロイメントの自動化のためのパイプライン、などを完全に管理するソリューションです。このユースケースでは、リポジトリとパイプラインの両方を使用します。

Azure DevOpsリポジトリにはTerraformインフラプロビジョニング用のソースコードを保持し、Azureパイプラインはterraformコマンドを実行します。

事前準備

  1. セキュアなファイルをAzure DevOpsポータルにアップロードする必要があります。このファイルはプロファイルセクションのTerraformがシークレットキーとアクセスIDを使用するためのパイプラインで使用されます。

azure-pipelines.yml パイプラインをコードとして使用し、Terraformを使ってデプロイを自動化します。コードにはDevとProdのステージが含まれており、terraformコマンドが含まれています。

認証情報ファイルは以下のようになります。

Credential file

AzureDevOpsポータルでのセキュアファイルアップロード

Secure file upload

azure-pipelines.yml ファイル内容。

# スターターパイプライン
# 最小限のパイプラインから始めて、コードのビルドとデプロイができるようにカスタマイズします。
# ビルド、テストの実行、デプロイなどのステップを追加します:
# https://aka.ms/yaml

trigger:
- main

pool:
  vmImage: ubuntu-latest

stages:    
  - stage: Dev
    displayName: Dev
    jobs:
      # 各ステップ詳細は省略...

  - stage: Prod
    displayName: Prod
    jobs:
      # 各ステップ詳細は省略...

全画面モードで終了

ワークフロー4、5

パイプライン内のステージを通して歩みましょう。

Devステージのジョブタスク

  1. セキュアファイルをダウンロード

このタスクはセキュアファイルをエージェントの一時フォルダにダウンロードします。

  1. セキュアファイルをコピー

このタスクは、terraformプロバイダセクションでこのパスを参照しているために、あらかじめセキュアファイルを一時フォルダからエージェントのホームディレクトリにコピーします。

terraform providers.tf ファイル内容

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
  }
  backend "s3" {}
}

provider "aws" {
  region                   = var.aws_region
  shared_credentials_files = ["~/.aws/credentials"]
  profile                  = "vscode"
  assume_role {
    role_arn = var.aws_assume_role_arn 
  }
}

全画面モードで終了

3. Terraform init

Terraformの初期化では、バックエンドステートとしてS3バケットを使用します。

事前準夙

  • 開発用および本番用AWSアカウントに対してterraformステートを維持するためのS3バケットを作成します。

  • それぞれのAWSアカウントに対してterraformロックを維持するためのdynamodbを作成します。

  • バックエンド設定にはロール名が含まれている必要があります。

dev-backend.conf ファイル内容

# 利用するS3バケット、キー、リージョン、DynamoDBテーブルなどのバックエンド設定

全画面モードで終了

prod-backend.conf ファイル内容

# 同じように、本番環境のS3バケット、キー、リージョン、DynamoDBテーブルなどを設定

全画面モードで終了

Terraform init コマンド:
terraform init -reconfigure -backend-config="dev-backend.conf"

ここで -reconfigure およびバックエンド設定を使用しています。これにより、環境設定ファイルに基づいて対応するAWSアカウントのterraformステートs3バケットが正しく設定されます。

4. Terraform plan
Terraform planはインフラの状態とコードの変更からの現在の望ましい状態を比較するために使用され、私たちのインフラにおける変更点を提示します。

Terraform plan コマンド:
terraform plan --var-file="dev-app.tfvars" -var createdBy="dev-pipeline" -var tags="asd" -out main.tfplan

ここでは、開発環境固有の値を渡す必要があります。

dev-app.tfvars ファイル内容

# 共通項目
# 各種リソースのVPCやサブネットなどの設定

全画面モードで終了

プラン完了後、結果を確認できます。

Terraform plan

4. Azure DevOps Terraform plan のレビューと承認、あるいは拒否
この承認ゲートにより、terraform planをレビューして、インフラに対して行う変更を理解する手助けをしてくれます。

Approval

5. Terraform apply
Azure DevOpsパイプラインでは、新しいジョブ定義を使用しているため、ダウンロード、セキュアファイルのコピー、terraform initタスクを定義する必要があります。

Terraform apply コマンド
terraform apply --var-file="dev-app.tfvars" -var createdBy="dev-pipeline" -var tags="asd" --auto-approve

ここでは、既にterraform planをレビューしたので auto-approve を渡す必要があります。

terraform applyが完了すると、AzureDevOpsパイプラインのステータスが確認できます。

Terraform apply

Result

注意: 本番ステージでも、同様のコンセプトを使用し、異なる環境変数ファイルを渡す必要があります。

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/sathishsundaram/how-to-use-terraform-in-aws-multi-account-via-azuredevops-pipelines-5h3j