• 337 Words

    Terraform で空の AWS Lambda Function を作る方法

    Terraform で空の AWS Lambda Function を作ろうとした際にちょっとハマったのでやり方を書いておきます。 「空の Lambda Function」という表現は適切ではないかもしれませんが、 Lambda で実行するコードのデプロイは Terraform 以外のツールでやるけど、 Lambda Function の作成は Terraform で行うので、 dummy のコードを指定して Terraform で Lambda を作るという話です。 自分は今は lambroll というツールで Lambda をデプロイしています。 lambroll は Lambda Function も作ってくれるので Terraform で作る必要は必ずしもありません。 しかし Lambda Function に関連するリソースを Terraform で管理する場合、 Lambda Function も Terraform で作ると Lambda Function の ARN や Invoke ARN を参照できます。 また lambroll でデプロイする場合も先に Terraform で IAM Role を作成する必要がありますが、 Terraform で aws_lambda_permission のようなリソースを作成するには Lambda Function が先に作られている必要があるので、 互いに依存関係が発生し、面倒なことになります。
    • 164 Words

    terraform init で lock ファイルが更新される問題の対応

    Terraform v0.14 で local で terraform init すると lock ファイルが更新されてしまう問題に対応しました。 結論を最初に言うと、 100 以上の Terraform 環境をいい感じに v0.14 に upgrade した方法で紹介している方法で Renovate で Terraform Provider を update する際に terraform init -upgrade を実行して lock ファイルを更新してコミット・プッシュしているのですが、 その際に terraform providers lock -platform=darwin_amd64 を実行するようにしました。 Terraform v0.14 で lock ファイル .terraform.lock.hcl が導入されました。 Renovate で Terraform Provider を update する際にも lock ファイルを更新する必要があるので、 terraform init -upgrade を実行して lock ファイルを更新してコミット・プッシュしています。 なのですが、ローカルで terraform init を実行するとなんか lock ファイルが更新されることが良くありました。しばらく放置していたのですが、 developer から「なんかファイル更新されたんだけど、これコミットしていいの?」と聞かれ、このまま放っておいて困惑させたりもやっとさせたりするのは良くないなと思い、調べてみました。 lock ファイルについて .
    • 150 Words

    Terraform Module の Template という使い方

    Terraform Module の使い方として Terraform Module のテンプレートをコピペして使うというアプローチを紹介します。 Terraform の設定ファイル(以下 tfファイル) を書く際、毎回一から書くのは大変です。 多くの場合、既存のコードを再利用したほうが楽でしょう。 Terraform のコードの再利用の仕組みとして、 Module があります。 Module は勿論便利なのですが、使い方には注意が必要で、「安易に Module 化するな。使うな」というふうな考え方もあるでしょう。 自分も基本的に同意見で、 Module を共用するようになると Module への変更がしづらくなったり、パラメータがどんどん増えて複雑になったりします。 例えば次のように共用の local Module を作成するアプローチがあります。 modules/ lambda-base/ README.md main.tf variables.tf outputs.tf services/ foo/ staging/ main.tf # リポジトリ直下の modules/lambda-base を参照 production/ main.tf # リポジトリ直下の modules/lambda-base を参照 こうすると modules 配下の Module を変更した際にその Module を使っているすべてのサービスに影響が出てしまい、 サービスのオーナーが様々だったり、曖昧だったり不在だったりすると変更が難しいですし、どんどん Module が複雑になったりします。 Module を別のリポジトリでバージョニングして管理し、バージョンを指定するようにするというやり方もありますが、 結構複雑というか考えることが多いアプローチだとは思います。 Terraform にそこまで詳しくない developer にも書いてもらうとなると、シンプルなアプローチにするのが望ましいでしょう(当然これは組織によりますが)。 そこで Module のテンプレートを用意し、 Module を使いたくなったらそれをコピペして使うというアプローチがあります。 例えば lambda-base という Module の Template を foo というサービスの staging 環境と production 環境で使う場合、次のような感じになります。
    • 457 Words

    terraformer で雑に生成した tf ファイル と state を分割したくてツールを書いた

    terraformer で雑に生成した Terraform の設定ファイル (以下 tf ファイル) と state を分割したくてツールを書きました。 tfmigrator 経緯 miam から Terraform へ移行したい miam というツールで管理されている大量のリソースを Terraform で管理したくなりました。 多くの AWS Resource は Terraform で管理されていますが、 IAM に関しては miam で管理されています。 なぜ Terraform ではなく miam で管理されているかというと、当時のことは自分には分かりませんが、歴史的な経緯もあると思います。 昔は今よりも Terraform の表現力が豊かではなく、 Ruby で自由にかける miam のほうが扱いやすかったとか、 miam だと miam でリソースを管理することを強制できるため、権限管理を厳格にやるという観点では都合が良いという点もあるかと思います。 ではなぜ Terraform で管理したくなったかというと、 一番大きな理由は miam で頻繁に rate limit に引っかかるようになったからです。 Terraform にしろ miam にしろ CI/CD で test, apply が実行されるようになっています。 miam では毎回全部のリソースを対象に処理が実行されるため、リソースの数が増えるにつれて rate limit に引っかかりやすくなります。 CI を rerun すれば成功するのですが、悪いときは 3 回連続で rate limit に引っかかり、 4 回目でようやく成功するということもありました。
    • 64 Words

    tfnotify を fork した

    mercari/tfnotify を Fork して 2 つほど OSS を作りました。 https://github.com/suzuki-shunsuke/tfnotify - tfnotify と互換性あり https://github.com/suzuki-shunsuke/tfcmt - tfnotify と互換性がない 開発の経緯 これまで tfnotify を便利に使わせてもらってたのですが、幾つか改善したいと思うところがあり、本家に PR を投げました。 しかし残念ながらこれまでのところ反応がなく、そこまで本家が活発ではないこと、また他にも色々改修したいところがあったことから、自分でフォークしてメンテすることにしました。 最初は互換性を維持しながら suzuki-shunsuke/tfnotify を開発していました(今もしています)。 しかし、開発を進めるに連れ、自分にとって必要のないプラットフォームなどに関するコードが邪魔であると感じ、それらを消したバージョンを別に開発することにしました。 互換性がなくなることから、名前も変えて tfcmt としました。 https://github.com/suzuki-shunsuke/tfcmt こういった経緯から、 tfcmt のほうを優先的に開発していますが、 tfcmt で実装した機能を後から suzuki-shunsuke/tfnotify にも実装してたりもします。 Fork 元のバージョン suzuki-shunsuke/tfnotify は mercari/tfnotify v0.7.0 fb178d8 をフォークしました。 一方 tfcmt は suzuki-shunsuke/tfnotify v1.3.3 をフォークしました。 mercari/tfnotify との違い 本家との違いは Release Note とドキュメントを参照してください。 suzuki-shunsuke/tfnotify https://github.com/suzuki-shunsuke/tfnotify/releases https://github.com/suzuki-shunsuke/tfnotify/blob/master/COMPARED_WITH_TFNOTIFY.md suzuki-shunsuke/tfcmt https://github.com/suzuki-shunsuke/tfcmt/releases https://github.
    • 92 Words

    Terraform の Docker Provider の Collaborator になりました

    先日 kreuzwerker/terraform-provider-docker の Collaborator になりました。 kreuzwerker/terraform-provider-docker は Terraform の Docker Provider であり、 Docker コンテナや image, network などを管理できます。 元々は Hashicorp の Official Provider であった terraform-providers/terraform-provider-docker が kreuzwerker/terraform-provider-docker に移管され、 Community Provider になりました。 元のリポジトリは hashicorp org に移され archive されています。 Collaborator になった経緯 リポジトリが移管される際に、メンテナを募集していて過去に contribution していた自分にも声をかけていただきました。 https://github.com/hashicorp/terraform-provider-docker/issues/306 Contributor になった経緯 自分がこの provider に contribution した経緯は、 Terraform の Hands on を書くのに丁度よい provider を探していたことでした。 Hands on の題材として Docker コンテナを作ったりできたらいいんじゃないかなと思って Docker provider を試してみました。 しかし当時の docker_container リソースは read をちゃんとサポートしていませんでした。 なので import や update がまともに動きませんでした。 それを見かねて修正して PR を投げたのが最初です。
    • 146 Words

    tfnotify の parse error を通知する

    tfnotify が terraform の標準出力のパースに失敗してコメントを投稿できないことがあります。 コメントを投稿できなくてもビルドのログには残るのですが、やはりコメントを投稿できると便利なので、tfnotify がパースエラーでコメントの投稿に失敗したら、 github-comment でコメントを投稿するようにしました。 なお、この記事を書いている時点のバージョンは tfnotify v0.7.0, github-comment v1.9.0 です。 例えば tfnotify plan がパースエラーになった場合、 cannot parse plan result というメッセージが標準エラー出力されます。 そこで標準エラー出力に cannot parse plan result が含まれていたら github-comment でコメントするようにします。 terraform plan | github-comment exec -k plan -- tfnotify plan .github-comment.yml # 細かく template を分けているが、別に分けなくてもよい templates: # header は CodeBuild の場合 header: '{{Env "TARGET"}} [Build link]({{Env "CODEBUILD_BUILD_URL"}})' exit_code: ':{{if eq .ExitCode 0}}white_check_mark{{else}}x{{end}}: Exit Code {{.ExitCode}}' join_command: |``` $ {{.JoinCommand}} ``` hidden_combined_output: |<details> <pre><code>{{.
    • 4132 Words

    Terraform ハンズオン with MySQL Provider

    Terraform を勉強するには実際に使ってみるのが一番手っ取り早いですが、 では手頃な題材はあるかと言われると少し難しいです。 公式の Getting Started では AWS が使われていますが、 AWS のアカウントやクレデンシャルが必要ですしお金もかかってしまいます(無料枠はありますが)。 もう少し手軽なものが欲しいところです。 そこで公式の Provider で丁度いいものはないか探したところ、 MySQL Provider が良さそうでした。 MySQL のユーザーや Database を Terraform で管理したいとは自分は思いませんが、 Terraform の入門で遊ぶにはちょうどよいでしょう。 ちなみに公式の Provider のリストはこちらです。 https://github.com/terraform-providers https://www.terraform.io/docs/providers/index.html また、 Terraform に関しては Terraform 入門 も参照してください。 今回の作業用に適当にディレクトリを作成し、そこで作業しましょう。 以降、コマンドの実行結果は一部省略することがあります。 $ mkdir workspace $ cd workspace Terraform のバージョンと tfenv Terraform を複数人で使う場合、 Terraform のバージョンを揃えるのが重要です。 理由の一つとして、 Terraform の State は State を作成した Terraform のバージョンを記録しており、それより古いバージョンの Terraform で terraform plan などを実行すると失敗するようになっていることが挙げられます(この点については後でも触れます)。 そういう意味では、 tfenv によってバージョン管理するのが良いです。
    • 945 Words

    Terraform 入門

    参考 10分で理解するTerraform | Qiita Terraform入門資料(v0.12.0対応) ~基本知識から設計や運用、知っておくべきtipsまで~ | Qiita AWSでTerraformに入門 | Developers.io Terraform職人入門: 日々の運用で学んだ知見を淡々とまとめる | Qiita 手を動かしたい方は Terraform ハンズオン with MySQL Provider も参考にしてください。 前提 執筆時点 (2020/01/05) で Terraform の最新バージョンは v0.12.18 です Terraform とは Terraform は Infrastructure as Code を実現する汎用的なCLIツールです。 インフラの状態を設定ファイルに定義し、コマンドを実行することで、 実際のインフラの状態と設定ファイルの差分を検知し、設定ファイルに記述されたとおりになるようにインフラを変更(CRUD)します。 Hashicorp という企業がホストしている OSS になります。 Go で書かれています。 https://github.com/hashicorp/terraform Terraform のインストール Terraform は Go 製なので 1 バイナリをダウンロードしてインストールするだけです。 https://www.terraform.io/downloads.html tfenv を使うと管理が楽です。 https://github.com/tfutils/tfenv tfenv は Terraform のバージョン管理ツールです。 pyenv や rbenv の Terraform 版みたいなものです。
    • 450 Words

    Terraform の State Locking の概要

    Terraform の State Locking という機能の概要について説明します。 ただし、自分もちゃんと理解しているわけではないので、推測も混じります。 基本的には公式ドキュメントに書いてある内容なのでそちらをご参照ください。 State Locking とは terraform plan などのコマンドは State を変更する場合があります。 その処理は atomic ではないため、同時に複数のコマンドが State を書き換えようとすると不整合が生じる可能性があります。 例えば S3 backend の state を state rm で更新する場合を考えます。 これはコマンド内部で 現在の State を取得する (READ) 修正した State を S3 に push する (WRITE) という処理を行っているはずであり、複数のコマンドを実行した場合、READ と WRITE の間に他のコマンドによって WRITE されると、その WRITE による変更が消えてしまいます。 そこで State Locking を使うと各コマンドで State を変更する前に lock を取り、WRITE 後に lock を解除します。 コマンドラインオプション plan, apply, refresh, state rm, state mv, state push には次のようなオプションがあります。