[Terraform] Terragrunt + gcloud + tfnotify をdocker-composeで使う

はじめに

これは、自分が分析環境を作る際に用意したCI上でのTerraform環境の共有です。
開発環境用に作成したものはこちらです。

もっとよいやり方があるかもしれませんが、とりあえず自分がやったもの(オリジナルを一部改変したもの)を載せておきます。

Dockerfile

実際に使うために書いたものを少し改変したDockerfileは下記のとおりです。

tfnotifyで使用するGITHUB_TOKENに渡すトークンの生成時に付与する権限は、repoとwrite:discussionです。

GCLOUD_SERVICE_KEYには、サービスアカウントキーの文字列を渡します。

GCLOUD_PROJECT_IDには、GCPのプロジェクトIDを渡します。

APP_ENVはterragruntでデプロイする際に環境を切り替えるのに使用しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
FROM alpine/terragrunt:0.12.12

ARG GCLOUD_SERVICE_KEY
ENV GCLOUD_SERVICE_KEY ${GCLOUD_SERVICE_KEY}

ARG GCLOUD_PROJECT_ID
ENV GCLOUD_PROJECT_ID ${GCLOUD_PROJECT_ID}

ARG GITHUB_TOKEN
ENV GITHUB_TOKEN ${GITHUB_TOKEN}

ARG APP_ENV
ENV APP_ENV ${APP_ENV}

RUN apk add --no-cache curl \
    python3

WORKDIR /root/tfnotify/temp
RUN wget https://github.com/mercari/tfnotify/releases/download/v0.3.3/tfnotify_0.3.3_linux_amd64.tar.gz && \
    tar -zxvf tfnotify_0.3.3_linux_amd64.tar.gz && \
    mv tfnotify ../ && \
    cd ../ && \
    rm -rf temp
ENV PATH=$PATH:/root/tfnotify

RUN curl https://sdk.cloud.google.com | bash
ENV PATH=$PATH:/root/google-cloud-sdk/bin
RUN echo ${GCLOUD_SERVICE_KEY} | gcloud auth activate-service-account --key-file=- && \
    gcloud --quiet config set project ${GCLOUD_PROJECT_ID} && \
    gcloud --quiet config set compute/zone asia-northeast1

WORKDIR /usr/src/app

COPY . .

dcoker-compose.yml

CircleCIを使用しているので、docker-compose.production.ymlでは、CIRCLE系の環境変数を渡してtfnotifyが参照できるようにしています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.production
    environment:
      - CIRCLE_SHA1=$CIRCLE_SHA1
      - CIRCLE_BUILD_URL=$CIRCLE_BUILD_URL
      - CIRCLE_PULL_REQUEST=$CIRCLE_PULL_REQUEST
      - CI_PULL_REQUEST=$CI_PULL_REQUEST
      - CIRCLE_PR_NUMBER=$CIRCLE_PR_NUMBER
    volumes:
      - .:/usr/src/app

CircleCIのconfig.yml(一部抜粋)は、下記のように設定しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
commands:
  setup:
    parameters:
      service_key:
        type: env_var_name
      project_id:
        type: string
      env:
        type: string
    steps:
      - run: |
          docker-compose -f docker-compose.production.yml build \
            --build-arg GCLOUD_SERVICE_KEY="${<<parameters.service_key>>}" \
            --build-arg GCLOUD_PROJECT_ID=<<parameters.project_id>> \
            --build-arg GITHUB_TOKEN=${GITHUB_TOKEN} \
            --build-arg APP_ENV=<<parameters.env>> \
            app          

deploy shell

terragruntのplan-allやapply-allの標準出力をtfnotifyに渡してもうまく解釈されないため、自分は下記のようなシェルを書いて対応しました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
current_directory=`pwd`
cd `dirname $0`

services_directory=../../services

for directory_name in `ls ${services_directory}`
do
  cd ${services_directory}/${directory_name}
  terragrunt $1 `[ $1 = apply ] && --terragrunt-non-interactive` | tfnotify --config ../../tfnotify.yml $1 --message `pwd`
done

cd $current_directory
1
2
3
cd `dirname $0`

./base.sh plan
1
2
3
cd `dirname $0`

./base.sh apply

(一部抜粋した)ディレクトリ構造は下記のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
├── Dockerfile
├── Dockerfile.production
├── script
│   └── terragrunt_with_notify
│       ├── apply_all_service.sh
│       ├── base.sh
│       └── plan_all_service.sh
├── services
├── terragrunt.hcl
└── tfnotify.yml
Built with Hugo
テーマ StackJimmy によって設計されています。