9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

terraform を upgradeしてtflintをいれる

Last updated at Posted at 2022-03-10

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自体はできますが一応明示しておきましょう。

main.tf

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*
main.tf

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 で渡して実行するようにしています。

.aws_tflint.chl
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
}
gcp_tflint.chl
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にすれば回避できるかもしれません)

実行

.tflint.hclの準備ができたら実行します。
それぞれのカレントディレクトリに移動し
tflint --config .aws_tflint.chltflint --config .gcp_tflint.chl を実行します。
circle ci上でも同様です

まとめ

terraformをupgradeすることで moved block などの新機能を使ってIaCを定義することができ
linterを導入することで、ルールを強制しterraformの管理コストなどをある程度軽減できるようになりました。

DMMではビッグデータ基盤関連の運用を行っており、
様々リソースを活用したプロダクト開発も行っています。
中途採用などもおこなっておりますので、興味のある方は、一度弊社HPなどから
カジュアル面談など、是非ご応募ください。

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?