DMMのyuuaです
terraformのupgradeとtflintの導入を行ったのでその際の手順的な備忘録です。
upgrade
使用していたterraformのversionが 0.14
系だったのでそこから 1.1.x
までupgradeしました。
0.13以前のversionの場合は0.1系ずつあげていく必要がありますが、0.14以降であれば一部versionをskipしての
upgradeも可能なようです。ただ0.14系から1.0.x系に上げる場合は0.15系へのupgrade guidを確認してからupgradeしましょう。
私のチームでのterraform環境は circle ci
上で terraform を実行しています。
そのため各versionの docker image
を作成し、ECR上で管理します。
baseとなるdocker imageは hashicorp/terraformを使用します
1.0.x化
FROM hashicorp/terraform:1.0.x
# aws cli
RUN apk --update --no-cache add python3 py3-pip curl && pip3 install --no-cache-dir --upgrade pip awscli
# tfnotify
ENV TFNOTIFY_VERSION=0.7.0
RUN wget https://github.com/mercari/tfnotify/releases/download/v${TFNOTIFY_VERSION}/tfnotify_linux_amd64.tar.gz -O tfnotify.tar.gz \
&& tar -xf tfnotify.tar.gz -C /usr/local/bin/ \
&& chmod u+x /usr/local/bin/tfnotify \
&& rm tfnotify.tar.gz
# gcloud
ENV GCLOUD_VERSION=337.0.0
RUN curl -o google-cloud-sdk.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GCLOUD_VERSION}-linux-x86_64.tar.gz \
&& tar -xf google-cloud-sdk.tar.gz -C $HOME \
&& $HOME/google-cloud-sdk/install.sh --quiet \
&& rm google-cloud-sdk.tar.gz
ENV PATH $PATH:/root/google-cloud-sdk/bin
1.0.x系の docker imageを使用し、 apply
に際し必要なものやその他必要なツール類をimageに含めるように作成します。(ここではgcloud-sdk / tfnotifyをいれています)
main.tfの required_version
を変更しておく、変更しなくてもplan/apply自体はできますが一応明示しておきましょう。
terraform {
required_version = ">= instalしたterraformのversion指定"
required_providers {
....
}
}
.....
....
...
..
terrform plan
を実行し no change であることが確認できたら terraform apply
を実行します。
changeやdeprecatedなどがでた際は対応しましょう。
1.1.x化
基本的に1.0.x化と同様にimage上のterraformをupgradeするだけです。
今回はtflintもいれるのでlinterを追加しています。
tflintのversionに関してはterraformのversionと互換性があるversionをいれてください
また、tflintにはinstall shellが用意されていますが、 hashicorp/terraform:1.1.x
のimage上で実行すると unzip
でエラーが発生するため
install shellは使用していません。
FROM hashicorp/terraform:1.1.x
.....
....
...
..
# tflint
ENV TFLINT_VERSION=v0.34.1
ENV OS=linux_amd64
RUN curl --fail --silent -L -o /tmp/tflint.zip "https://github.com/terraform-linters/tflint/releases/download/${TFLINT_VERSION}/tflint_${OS}.zip" \
&& unzip /tmp/tflint.zip -d /tmp/ \
&& install -c -v /tmp/tflint /usr/local/bin/ \
&& rm /tmp/tflint*
terraform {
required_version = ">= instalしたterraformのversion指定"
required_providers {
....
}
}
.....
....
...
..
こちらも同様に、terrform plan
を実行し no change であることが確認できたら terraform apply
を実行します。
changeやdeprecatedなどがでた際は対応しましょう。
tflintの導入
tflintを導入することでルールを強制することができます。また主要なプロバイダー(aws/gcp/azure)などのルールセットはgithub上にreleaseされているのでそちらを使用します。
(tflintのversionに関してはterraformのversionと互換性があるversionをいれてください)
tflintのdocker imageの追加自体は1.1.x化の際に対応してあります。
ENV TFLINT_VERSION=v0.34.1
ENV OS=linux_amd64
RUN curl --fail --silent -L -o /tmp/tflint.zip "https://github.com/terraform-linters/tflint/releases/download/${TFLINT_VERSION}/tflint_${OS}.zip" \
&& unzip /tmp/tflint.zip -d /tmp/ \
&& install -c -v /tmp/tflint /usr/local/bin/ \
&& rm /tmp/tflint*
pluginの追加
pluginを事前に .tflint.d
に配下にインストールしておくことで都度インストールすることを回避できます。
私のチームでは aws/gcp の2つのクラウド環境を利用しているため
tflint-ruleset-aws
tflint-ruleset-google
の2つを事前にインストールしています。
docker image上で実行しているため事前にインストールしておかないと tflint --init
のたびにインストールしてしまいます。
# tflint bundle plugin
ENV TFLINT_AWS_VERSION=0.12.0
ENV TFLINT_GOOGLE_VERSION=0.15.0
RUN mkdir -p ~/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/${TFLINT_AWS_VERSION}/ \
&& wget -O /tmp/tflint-ruleset-aws.zip https://github.com/terraform-linters/tflint-ruleset-aws/releases/download/v${TFLINT_AWS_VERSION}/tflint-ruleset-aws_linux_amd64.zip \
&& unzip /tmp/tflint-ruleset-aws.zip -d ~/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/${TFLINT_AWS_VERSION}/ \
&& rm /tmp/tflint-ruleset-aws.zip \
&& mkdir -p ~/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/${TFLINT_GOOGLE_VERSION}/ \
&& wget -O /tmp/tflint-ruleset-google.zip https://github.com/terraform-linters/tflint-ruleset-google/releases/download/v${TFLINT_GOOGLE_VERSION}/tflint-ruleset-google_linux_amd64.zip \
&& unzip /tmp/tflint-ruleset-google.zip -d ~/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/${TFLINT_GOOGLE_VERSION}/ \
&& rm /tmp/tflint-ruleset-google.zip
tflintの設定
.tflint.chl
で ルールの設定などをします。
-
.tflint.chl
は $HOME下もしくはカレントディレクトリにおくとoptionを指定する必要がなく読み込まれます。
私のチームでは
├── terraform
│ ├── aws
│ │ ├── ap-northeast-1
│ │ │ ├── dev
│ │ │ │ ├── main.tf
│ │ │ └── prd
│ │ │ ├── main.tf
....
...
│ │ ├── modules
│ │ │ ├── hogehoge
│ └── google
│ ├── modules
│ │ ├── hogehoge
│ │ └── shared
│ │ ├── dev
│ │ ├── main.tf
│ │ │ └── prd
│ │ │ ├── main.tf
....
...
このようなディレクトリ構成でterraformを管理しており、複数のクラウド環境へ apply
を実施しているため
下記のようにクラウドごとの .tflint.chl
を作成しそれを --config
で渡して実行するようにしています。
plugin "aws" {
enabled = true
version = "0.12.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
deep_check = true
}
config {
module = true
}
rule "terraform_required_version" {
enabled = true
}
rule "terraform_unused_declarations" {
enabled = true
}
rule "terraform_unused_required_providers" {
enabled = true
}
plugin "google" {
enabled = true
version = "0.15.0"
source = "github.com/terraform-linters/tflint-ruleset-google"
}
config {
module = true
}
rule "terraform_required_version" {
enabled = true
}
rule "terraform_unused_declarations" {
enabled = true
}
rule "terraform_unused_required_providers" {
enabled = true
}
$HOMEに .tflint.chl
を設置して、実行でも良いですが、その場合 各クラウドの設定の tflintの deep_check=true
をした場合
awsのリソースのlinterなのにgcpのクレデンシャルが必要になってしまいます。(deep_checkのフラグをあげた状態で tflint
を実行すると apiへの接続などを確認する際にクレデンシャルを使用するためだと思われます。ルールの使用をdisableにすれば回避できるかもしれません)
- deep_checkは外部のAPI(aws/gcpなど)を使用して厳密なチェックを行うようにするフラグ
- ルールの定義などはDocumentを確認してください。
defaultルール
aws pluginのルール
gcp pluginのルール
実行
.tflint.hclの準備ができたら実行します。
それぞれのカレントディレクトリに移動し
tflint --config .aws_tflint.chl
や tflint --config .gcp_tflint.chl
を実行します。
circle ci上でも同様です
まとめ
terraformをupgradeすることで moved block
などの新機能を使ってIaCを定義することができ
linterを導入することで、ルールを強制しterraformの管理コストなどをある程度軽減できるようになりました。
DMMではビッグデータ基盤関連の運用を行っており、
様々リソースを活用したプロダクト開発も行っています。
中途採用などもおこなっておりますので、興味のある方は、一度弊社HPなどから
カジュアル面談など、是非ご応募ください。