ソースコード管理に GitLab を使っているんですが、いつの頃からか Terraform の tfstate を管理する機能が追加されていました。(公式ドキュメントを見ると GitLab 13.0 から追加されたようです)
AWS で state を管理する場合、S3 と DynamoDB を組み合わせて管理、共有することが多いと思います。他の方法だと Terraform Cloud を使う方法もありますね。GitLab でコードの管理、CI/CD を行っている場合は、Terraform の state も一緒に管理すると、自ずと開発チームで共有でき、パイプラインでリソースの作成、廃棄が管理できて便利でした。
今回は GitLab で Terraform の state を管理し、CI/CD で環境構築を行う方法についてご紹介します。
詳細は GitLab のヘルプページも参考にしてください。
GitLab-managed Terraform state
今回 AWS 上に作成した環境はこのようなシンプルな環境です。
VPC にパブリックサブネットを1つ作成し、t2.micro の EC2 で Web サーバーを作成します。インターネットゲートウェイを設置してインターネットにアクセスできるようにしています。
ここには記載していませんが、HTTP:80 のインバウンド通信をセキュリティグループで許可しています。
このリポジトリはこちらで公開しています。
まずは Terraform の準備を行います。以下のような main.tf を作成して、terraform init
を実行しました。
GitLab をバックエンドとして使用するために、backend.tf を作成します。
続いて、GitLab を state 管理のバックエンドとして使用するように設定します。
コマンドを実行して設定しますが、GitLab のリポジトリのメニューにある[インフラ] > [Terraform]から確認できるコマンドのほうがわかりやすいので、一旦ここまでの状態でコミットして、リポジトリメニューの[インフラ]から確認するほうがいいかもしれません。
コマンドの実行時にパーソナルアクセストークンが必要になるので、事前に払い出しておく必要があります。
パーソナルトークンの払い出し方はこちらを確認してください。
バックエンドの設定コマンドの例はこちらです。
コマンドを実行すると .terraform フォルダが作成されます。
GitLab で CI/CD を行うには、.gitlab-ci.yml を作成します。terraform を使ったデプロイを行うための設定ファイルはこちらを参考にしました。before_script: のなかでリポジトリに設定した変数を使用して AWS アカウントやシークレットキーを取得しています。
include: で GitLab が公開しているテンプレート Terraform/Base.gitlab-ci.yml を読み込み、各ステージの extends: で定義されている .terraform:fmt などで include したテンプレートに記載されている処理を実行します。
extends: で実行される各処理はこちらのテンプレートを確認してください。
あとは VPC や EC を作成するテンプレートファイルを作成して、リポジトリに push すればパイプラインで処理が行われ、設定ファイルに記載の AWS アカウントにインフラを構築できます。
GitLab で state を管理し、CI/CD で AWS にインフラを構築することができました。一通り検証が終わって環境を削除するにはどうしたらいいでしょうか?
リポジトリをもう使わないようであれば、ローカルでいつものように terraform destroy としてしまっても良いかもしれませんが、一日の終りに環境を削除して、次の日にまた使いたい場合、ローカルで destroy してしまうと GitLab で管理された state と実態がそぐわなくなってしまいます。
そこで、destroy も GitLab のパイプラインで実行できるように、.gitlab-ci.yml を修正します。
次のように .gitlab-ci.yml を編集します。
変更点としては、destroy のステージを追加し、変数 $TF_DESTROYの値を確認して、build や deploy、destroy を実行するかどうかを制御するようにします。
また、deploy がスキップされ、destroy ステージで AWS 上のリソースが削除されます。
$TF_DESTROY を true にしてパイプラインを実行するには、リポジトリのメニューの[CI/CD] > [パイプライン] で [Run pipline]をクリックします。
その後、Variable でキーに TF_DESTROY、値に true を指定すれば OK です。何も入力せずに Run pipeline をすると deploy が行われ destroy がスキップされます。
こうすることでリソースを削除することができました。
参考: Terraform template recipes
GitLab を使って Terraform の state 管理をやってみましたが、開発メンバーとの共有や、CI/CD に組み込むことができ、とても便利でした。
これらの設定すべてをリポジトリ1つで管理できるのもシンプルです。GitLab を利用されている方や、インフラエンジニアを目指されている方にとって少しでもお役に立てたら幸いです。
Linkup では AWS でのインフラ設計、構築のご支援をしています。AWS でのインフラの新規構築やオンプレからの移行などのご相談も承っていますので、お困りのことがありましたらぜひご相談ください。