🎈

GitHubActionsとTerraformerを利用して既存のAWS環境をTerraformで管理する

2020/11/04に公開

はじめに

既に運用している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