升级Terraform并安装Tflint

我是DMM的yuua。
由於進行了terraform的升級和tflint的導入,以下是該過程的步驟備忘錄。

升级

由于使用的 Terraform 版本是 0.14 系列,所以升级到了 1.1.x。如果是 0.13 以前的版本,则需要逐步升级到 0.1 系列,但是在 0.14 以后的版本可以跳过一些版本进行升级。不过,如果是从 0.14 系列升级到 1.0.x 系列,则在升级之前应先查看 0.15 系列的升级指南。

在我的团队中,我们使用Circle CI来执行Terraform环境。因此,我们会创建每个版本的Docker镜像,并在ECR上进行管理。

请使用 hashicorp/terraform 作为基础 Docker 镜像。

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镜像,创建一个包含应用所需和其他必要工具的镜像,并在其中安装gcloud-sdk / tfnotify工具。

可以更改 main.tf 文件中的 required_version 版本,并对此进行明确说明,即使不更改版本,也可以执行 plan/apply 操作。


terraform {
  required_version = ">= instalしたterraformのversion指定"

  required_providers {
       ....
    }
  }
.....
....
...
..

如果执行terraform plan后确认没有任何更改,那么就执行terraform apply。如果出现了更改或废弃等情况,那就要进行相应的处理。

转为1.1.x版本

基本上,只需要在图像上升级terraform,就像1.0.x版本一样。由于我们还包括tflint,所以也添加了代码检查工具。

请将与terraform版本兼容的版本安装在tflint的版本中。此外,虽然tflint提供了安装脚本,但是在hashicorp/terraform:1.1.x的镜像上运行时会出现解压错误,因此我们不使用安装脚本。

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 {
       ....
    }
  }
.....
....
...
..

在执行 terraform apply 前,我们也要像之前一样先执行 terraform plan,并确认没有任何变化。如果有任何改变或废弃的内容出现,我们要进行相应的处理。

在中国,只需要一种选择,将以下内容以中文进行改写:

使用tflint进行配置检查

通过引入tflint工具,可以强制执行规则。此外,针对主要提供商(如aws/gcp/azure)的规则集已在GitHub上发布,所以请使用那些规则集。
(请确保tflint的版本与terraform兼容)

在迁移至1.1.x版本时,已经添加了tflint的Docker镜像。

 

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*

添加插件

为了避免每次都要安装插件,你可以事先将插件安装在.tflint.d的目录下。在我的团队中,我们使用了两个云环境,即aws和gcp,因此我们事先安装了tflint-ruleset-aws和tflint-ruleset-google这两个插件。由于我们是在docker镜像上执行,如果不提前安装,每次执行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
}

将.tflint.chl文件放置在$HOME目录下,执行也可以,但是在这种情况下,如果对每个云端的设置进行了 tflint 的 deep_check=true ,则需要gcp的凭据,儘管aws的资源linter却需要gcp的凭据。(在带上deep_check标志的情况下执行tflint时,可能是为了在检查连接到api时使用凭据。也许可以通过禁用规则来避免这个问题。)

    • 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,可以利用新功能,如Move Block等来定义基础设施即代码(IaC)。
通过引入linter,可以强制执行规则,从而在一定程度上减轻Terraform的管理成本等。

在DMM,我们负责大数据基础设施的运营,并且也进行了利用各种资源进行产品开发的工作。我们也正在进行中途招聘等活动,因此如果您有兴趣,请通过我们公司的网站等渠道,尽快申请面谈等,期待您的应聘。