hiko1129's note

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

2019/11/16

はじめに

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

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

Dockerfile

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

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

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

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

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

Dockerfile.production
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が参照できるようにしています。

docker-compose.production.yml
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(一部抜粋)は、下記のように設定しています。

.circleci/config.yml
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に渡してもうまく解釈されないため、自分は下記のようなシェルを書いて対応しました。

script/terragrunt_with_notify/base.sh
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
script/terragrunt_with_notify/plan_all_service.sh
cd `dirname $0`

./base.sh plan
script/terragrunt_with_notify/apply_all_service.sh
cd `dirname $0`

./base.sh apply

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

├── Dockerfile
├── Dockerfile.production
├── script
│   └── terragrunt_with_notify
│       ├── apply_all_service.sh
│       ├── base.sh
│       └── plan_all_service.sh
├── services
├── terragrunt.hcl
└── tfnotify.yml

終わりに

ちょうどこれ書き終わったぐらいで、GitHub Actionsが正式リリースされたので辛かった。
自分はbeta触ってみたりしてたけど、会社の方ではbeta登録できてなかったのか使えなかった。。。

ちょっと悩ましいところだけど、今のterraformだとterragrunt使う必要性は薄いかもしれない。
ちょっと調べた感じだと今だと旨味が減っている気がするし、結局ラッパーだから、terragruntに問題(開発終了)があったときにちょっと剥がすの面倒そうだなって思った。

「初terraformでterraformに対する知見がなかった」+「(分析基盤の開発なので)複数サービスを一つのリポジトリで扱う必要があった」+「分析基盤のすべて(Dataflow書いたり、ログ送信先のサーバをGoで書いたり)を全部一人でやっていたため余力がなかった」というところから作りに諸々の甘さや一般的なアプリケーション開発での構成と異なるところが見られるかもしれないが誰かに役にたったら嬉しい。

だいぶ会社の開発関連のモダン化が進んでいるのでこの調子で頑張りたい。ただ一人で進めるのはもう疲れた。
フロントやることに集中したい。Flutter書きたい。インフラ積極的に触りたくない。フルスタックすぎることをやめたい。というか会社にいるのに一人でもくもく開発し続けるのが嫌だ。一人でやるときは家に引きこもりたい。

誰かと一緒に開発しないときに、他の人に合わせて会社に出社(出社するのは世間ではまだ当たり前のことなんだけど)するのがまじで無理だ。非合理的だし、出社時間無駄だし、無駄に満員電車でストレス溜まるしやってられない。

一度これ意味ないなって思ってしまうと不快感がものすごいので(傲慢かもしれないが)早くなんとかなってほしいところ(まぁなんとかなると思っているので頑張れる)。


hiko1129

hiko1129
Twitter GitHub Qiita Qrunch Blog