/var/log/laughingman7743.log

I thought what I'd do was, I'd pretend I was one of those deaf-mutes or should I?

オレオレTerraform構成

もともとは同僚がシェルで書いていたラッパーです。シェルつらいかつ、CIが回せなかったのでPythonで書き直したものです。
こういったのもこそGoで書くのが良さそうですね。Terraformつらいって感じが伝われば😩

ラッパースクリプト自体はTerraformのコマンドとオプションを指定できるようにして、サブプロセスでTerraformを実行しているだけです。 ロールは カテゴリ/ロール 形式で指定します。Slackへの通知は、SNSをSlackに投げるLambdaを作成しています。SNSには整形したメッセージを投げ、Lambdaはトークンを追加してSlackに投げるだけの非常に簡単なものです。

実行環境はPipenv*1を使うと楽に構築できます。Pipenvちょー便利です!

ディレクトリ構成は以下

ステートの管理はS3、カテゴリやロールといった概念を導入して、全体・カテゴリ単位で共通に使える変数やバックエンド、プロバイダ、バージョン等の設定をテンプレートとして切り出しています。 カテゴリはVPCVPCに依存しないリソースを、VPC名やS3やSNSといったAWSのリソース名をつけて管理することを想定しています。ロールはサブネット名や適当な利用用途や業務用途の名前をつけて管理することを想定しています。ステージングとプロダクションの2つの環境を、変数値を変えることによって構築をすることを想定した構成です。カテゴリの共通変数には別カテゴリに属するロールのリモートステートを定義したりすると色々と捗ります。
テンプレートファイルは実行時に各ロールのディレクトリにコピーされるので、gitignoreファイルは以下の様にしています。IntelliJのHCLプラグイン*2はモリモリ補完が効くのでオススメです。

CIはJenkinsでGHPRB*3とMultibranchPipeline*4を併用して、プルリクではステージングとプロダクションのplanを実行してSlackに通知、developブランチではステージング環境のみapplyを実行してSlackに通知、masterブランチではプロダクション環境のみplanを実行してSlackに通知をしています。プルリクコメントに所定の形式でロール名を書くと、そのロールのみ実行するようなこともできるようにしています。

JenkinsはMasterノードのみDockerで上げて(EFS早く東京リージョンに来て欲しい)、実行自体はCodeBuildを使っています。CodeBuildもちょー便利です!

Terraformが利用するAWSAPIキーは全てのリソースをさわるのでAdmin権限が必要になります。CodeBuildはパラメータストアの値を簡単に取ってこれるので、パラメータストアにセキュアストリングで格納しています。APIキーの発行はしたくなかったのですが、AssumeRoleを使うとリモートステートへのアクセスが上手く行かなくなったので、仕方なくAPIキーの発行をしています😭

もうTerraformなしでは生きられない体に。。。素敵なTerraformライフを。

Enjoy!