GitHubActionsとTerraformerを利用して既存のAWS環境をTerraformで管理する
はじめに
既に運用しているAWS環境にて、Route53のドメイン一覧やセキュリティグループのIP一覧などを調査したい時に、構成管理していないと作業が大変な時があります。
そんな時にGoogleが提供しているTerraformerを使うと、既存の環境をTerraform定義ファイル生成してくれるので、コマンドラインベースで調査できるので便利です。
例えばRoute53のドメイン一覧などは、生成したファイルから以下のコマンド実行することでサクッと一覧を取得できます。
grep name ./generated/aws/route53/route53_record.tf | awk '{print $3}' | sort -u
ただ、構成管理していない組織では、AWSコンソールから勝手にでリソースを作成・変更・削除できるので、調査の都度Terraformerを実行し、最新の情報を取得する事になります。
そんな時はGitHubActionsを利用することで、自動かつリポジトリでTerraformerが生成する定義ファイルを管理する事ができます。
GitHubActions
name: 'Terraformer'
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
terraform:
name: 'Terraformer'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Install terraformer
env:
PROVIDER: aws
run: |
curl -LO https://github.com/GoogleCloudPlatform/terraformer/releases/download/$(curl -s https://api.github.com/repos/GoogleCloudPlatform/terraformer/releases/latest | grep tag_name | cut -d '"' -f 4)/terraformer-${PROVIDER}-linux-amd64
chmod +x terraformer-${PROVIDER}-linux-amd64
sudo mv terraformer-${PROVIDER}-linux-amd64 /usr/local/bin/terraformer
terraformer -v
- name: terraformer import
run: |
echo 'provider "aws" {}' > init.tf
terraform init
export resources=`terraformer import aws list`
set +e
for resource in ${resources} ; do terraformer import aws --resources=${resource} --regions=us-east-1 ; done
ls -lR
- name: Install tfsec
run: |
curl -LO https://github.com/tfsec/tfsec/releases/download/$(curl -s https://api.github.com/repos/tfsec/tfsec/releases/latest | grep tag_name | cut -d '"' -f 4)/tfsec-linux-amd64
chmod +x tfsec-linux-amd64
sudo mv tfsec-linux-amd64 /usr/local/bin/tfsec
tfsec -v
- name: tfsec check
run: |
tfsec ./generated/aws --out tfsec.json --format json -s
- name: git push files
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git commit -m "Add changes"
git push
実行タイミング
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
workflowの実行条件は、スケジュール実行と手動実行を定義しています。
UTC時間となる為、上記の場合はAM09:00/日次
での定期実行となります。
また、任意のタイミングでも実行できるようにworkflow_dispatch
も定義しています。
これによりGitHubActionsの画面から手動でworkflowの実行ができます。
Terraformのインストールとセットアップ
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
Terraformerを実行するには、Terraformコマンドが実行できる必要があるので、Terraformの公式のActionsによるインストールと、AWS公式のCredentials設定するActionsを実行しています。
AWSのアクセスキーの値は、GitHubSecretsから取得する為、事前にGitHubSecretsの登録が必要です。
Terraformerのインストール
- name: Install terraformer
env:
PROVIDER: aws
run: |
curl -LO https://github.com/GoogleCloudPlatform/terraformer/releases/download/$(curl -s https://api.github.com/repos/GoogleCloudPlatform/terraformer/releases/latest | grep tag_name | cut -d '"' -f 4)/terraformer-${PROVIDER}-linux-amd64
chmod +x terraformer-${PROVIDER}-linux-amd64
sudo mv terraformer-${PROVIDER}-linux-amd64 /usr/local/bin/terraformer
terraformer -v
Terraformerのインストール手順に従いインストールします。
今回はAWSのみの為PROVIDER
にはaws
しか指定していません。環境に応じて設定してください。
Terraformer importの実行
- name: terraformer import
run: |
echo 'provider "aws" {}' > init.tf
terraform init
export resources=`terraformer import aws list`
set +e
for resource in ${resources} ; do terraformer import aws --resources=${resource} --regions=us-east-1 ; done
ls -lR
TerraformのAWS Providerを取得後にimport
を実行します。
importするリソースは使用状況に応じて指定するのもいいですが、自分はhelp
の結果から対応しているリソースを取得して、全ての対応リソースを取得するようにしています。
環境や実行するIAMユーザーのロール次第で、取得に失敗するリソースが存在する為、実行前にset +e
にてコマンドのstatusを無視するようにしています。(これをしないと取得できないリソースがあった時点で、workflowが異常終了してしまいます。)
tfsecのインストール
- name: Install tfsec
run: |
curl -LO https://github.com/tfsec/tfsec/releases/download/$(curl -s https://api.github.com/repos/tfsec/tfsec/releases/latest | grep tag_name | cut -d '"' -f 4)/tfsec-linux-amd64
chmod +x tfsec-linux-amd64
sudo mv tfsec-linux-amd64 /usr/local/bin/tfsec
tfsec -v
tfsecはTerraformの静的解析ツールで、潜在的なセキュリティ問題をチェックできます。
もしTerraformによる構成管理の運用を開始した場合はCIで利用した方がいいので、事前に現時点でのリスクを認識できるように追加しています。
GitHubActions(terraform-security-scan)がありますが、こちらはプルリクに対してチェック結果をコメントしてくれるActionsで、今回とは利用シーンが合わないのでインストールして利用しています。
tfsecの実行
- name: tfsec check
run: |
tfsec ./generated/aws --out tfsec.json --format json -s
tfsecの実行結果もリポジトリで参照できるように、ファイル出力を指定しています。
出力形式は幾つがあるので、利用方法に合わせて指定可能です。
Select output format: default, json, csv, checkstyle, junit, sarif
セキュリティチェック結果に問題があるとコマンドは異常終了するので、workflowは失敗しないように-s
を設定します。
Github Security Alertsとして通知するGitHubActionsもあるようなのですが、Code scanning alerts
機能を有効化する必要があり、プライベートリポジトリで利用するにはEnterprise
契約でGitHub Advanced Security
をオプション購入する必要があるので断念しました。
git push
- name: git push files
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git commit -m "Add changes"
git push
terraformerにて生成したterraform定義ファイルと、 tfsecの結果をGitHubActions内でPushします。
.gitignore
terraformのディレクトリとtfstateファイルについては、リポジトリ管理する必要がないので、除外しておきます。
.terraform
*.tfstate
注意点
GitHubActionsの無料枠
AWSリソースが複数ある場合はworkflowの実行時間が長くなるので、GitHubActionsの利用時間を多く消費します。
GitHubの契約プラン次第で無料の利用時間は違うので、Organization内でのGitHubActionsの利用状況を把握しつつ、実行の頻度などを調整してください。
Discussion