今回は、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ファイルをコミットする方法をご紹介しました。
この記事をとおして、少しでも誰かのお役に立てれば幸いです。