AWS/Terraform

【Terraform】GitHubActionsでimportブロックの実行・生成ファイルのコミットを自動化してみた

今回は、TerraformのimportブロックをGitHubActionsで実行する方法をご説明します。
GitHubActionsのワークフロー内で、importブロックによって自動生成されたtfファイルを自動コミットします。
本記事ではAWSのリソースを対象としています。

 

さっそく結論

importブロックの実行・生成ファイルのコミットを自動化したGitHubActionsのymlファイルは以下です。
※プルリクエストをトリガーに terraform plan、マージをトリガーに terraform apply 実行するワークフローです。

▼リポジトリ/.github/workflows/terraform-plan.yml
・GitHubActionsとAWSとの接続はOIDCを利用しています。
・リポジトリ直下のimport.txt(事前に作成)の中身がtrueのときのみ、importブロックで指定したインポート対象のリソースのtfファイルを自動生成します。
・GitHubActions内で生成したファイルをリポジトリに保持するために、自動コミットの処理も行います。

name: terraform plan
on:
  pull_request:
    branches:
      - 'main'

permissions: write-all

jobs:
  plan:
    name: terraform plan
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v3

      - name: configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-region: ap-northeast-1
          role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }}
          role-duration-seconds: 1200

      - name: terraform setup
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.2

      - name: terraform init
        id: init
        run: terraform init
        working-directory: ./terraform
      
      - name: set import check value 
        run: echo "import=$(cat import.txt)" >> $GITHUB_ENV


############################################################################################
# terraform plan(import file generate)
############################################################################################
      - name: terraform plan and import
        if: ${{ env.import == 'true' }}
        id: plan_and_import
        working-directory: ./terraform
        run: |
         terraform plan -no-color -generate-config-out=generated.tf

      - name: Sed generate.tf
        if: ${{ env.import == 'true' }}
        run: sed -i s/true/false/g import.txt 
      
      - name: Set up Git user
        if: ${{ env.import == 'true' }}
        run: |
          git config --local user.email "actions@github.com"
          git config --local user.name "GitHub Actions"

      - name: Auto commit and push
        uses: stefanzweifel/git-auto-commit-action@v4
        if: ${{ env.import == 'true' }}
        with:
          commit_message: Automated Change
          file_pattern: './terraform/generated.tf import.txt'

############################################################################################
# terraform plan
############################################################################################
      - name: terraform plan
        id: plan
        working-directory: ./terraform
        run: |
         terraform plan -no-color 

▼リポジトリ/.github/workflows/terraform-apply.yml
・importブロックのために特別な記述していない、基本的な terraform apply を実行するワークフローです。
・importブロックを記述している場合は、terraform apply によってimportが完了します。

name: terraform apply
on:
  pull_request:
    types: [closed]
    branches:
      - 'main'

permissions: write-all

jobs:
  plan:
    name: terraform apply
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true
    steps:
      - name: checkout
        uses: actions/checkout@v3

      - name: configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-region: ap-northeast-1
          role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }}
          role-duration-seconds: 1200
      
      - name: terraform setup
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.2

      - id: init
        run: terraform init
        working-directory: ./terraform

      - id: apply
        working-directory: ./terraform
        run: |
         terraform apply -auto-approve -no-color 

 

やってみた

筆者の環境で実行した手順は以下です。

AWSでの作業

・インポート対象のS3バケットを作成します。
複数のリソースを同時にインポートしたいので、2つ作成しました。

GitHubでの作業

・Terraformの実行リポジトリを準備します。
ファイルの階層は以下です。

.
├── .github
│ └── workflows
│ ├── terraform-plan.yml
│ └── terraform-apply.yml
├── terraform
│ ├── terraform-config.tf
│ └── import-test.tf
│
└── import.txt

 

・のちほどプルリクエストを作成するために作業用のブランチを作成してチェックアウトしておきます。

・Terraformの動作設定は以下です。
▼リポジトリ/terraform/terrform-config.tf

############################################################################
# プロバイダ設定
############################################################################
provider "aws" {
  region = "ap-northeast-1"
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.6.2"
    }
  }
}

############################################################################
# バックエンド設定
############################################################################
terraform {
  backend "s3" {
    bucket         = "<バックエンドのS3バケット名>"
    key            = "terraform.tfstate"
    encrypt        = true
    region         = "ap-northeast-1"
    dynamodb_table = "<バックエンドのDynamonDBテーブル名>"
  }
}

・インポートブロックを記述します。
【注意】リソースブロックも記述してしまうと、terraform plan 実行時に自動でtfファイルが生成されません。
▼リポジトリ/terraform/import-test.tf

import {
  id = "20230701-terraform-import-test-1"
  to = aws_s3_bucket.test1
}

import {
  id = "20230701-terraform-import-test-2"
  to = aws_s3_bucket.test2
}

・リポジトリ直下にimport.txtを作成して、中身をtrueとします。
GitHubActionsのワークフロー内でのimport.txtの中身がtrueであれば自動でtfファイルを生成します。
▼リポジトリ/import.txt

true

・ワークフローのymlファイルの内容については冒頭のとおりです。

・作業用ブランチをコミットして、mainブランチへプルリクエストを作成します。

・GitHubActionsの terraform plan のワークフローがトリガーされます。

・ワークフローが実行し終わったら、インポート対象のresourceブロックが記述されたgenerated.tfが生成されてコミットされ、terraform plan が正常終了していることを確認します。
※ワークフロー内では、生成されたtfファイルが正しいか確認するため、追加で通常のterraform planを1回実行しています。
※合わせてimport.txtの中身をtrueからfalseに書き換えています。

・問題なければマージして、GitHubActionsの terraform apply のワークフローがトリガーされ、インポートが実行されます。

・念のため、terraform plan を実行すると、No Changesとなり、インポートが完了していることを確認しました。

補足:importブロックとは

importブロックとは、2023/6/12にリリースされたTerraformのバージョン1.5から実装された機能です。
importブロックは、Terraformで管理していない既存のリソースをTerraformの管理下にできる構文です。
これまでは terraform import コマンドを使用して、1つずつリソースをインポートし、コードを自身で作成する必要がありました。
importブロックを使用することで、複数のリソースのインポートを一度に実行でき、それらのコードを自動生成できるようになりました。

参考情報
HashiCorp⁠、Terraform 1.5をリリース
Import(公式ドキュメント)

おわりに

今回は、GitHubActionsでimportブロックを実行して、自動生成されるtfファイルをコミットする方法をご紹介しました。
この記事をとおして、少しでも誰かのお役に立てれば幸いです。