PipeCDを使ってTerraformをGitOps管理する

Table of Contents

tldr

GitOpsスタイルのCDであるPipeCDでTerraformを管理する方法を説明します。

PipeCDとは

PipeCDはOSSとして開発が進められている、マルチクラウドや複数のアプリケーションを統一されたGitOpsスタイルで継続的デリバリを行ってくれるソリューションです。インフラからアプリケーションまで、GitをSingle source of truthとして、変更があった場合に各環境へのデリバリーを実現します。

PipeCDでTerraformを管理する

PipeCDはKubernetes DeploymentやAWS ECSなどさまざまなアプリケーションを管理することができます。本記事ではTerraformの管理について説明していきます。

導入方法

PiceCDでTerraformを管理するための手順を説明します。 なお、ここではControl PlaneやPipedが既に導入されているところから説明していきます(導入方法についてはクイックスタートオペレーターマニュアルをご覧ください)。

Applicationの追加

Terraformアプリケーションの追加はUIでの追加とpipectlでの追加が可能です。

以下、pipectlで追加する場合のコマンドです。各フラグに渡す値は適宜変更してください。

pipectl application add \
  --address=${PIPECD_ADDRESS} \
  --api-key-file=path/to/apikey \
  --app-name=${APP_NAME} \
  --app-kind=TERRAFORM \
  --env-id=${ENV_ID} \
  --piped-id=${PIPED_ID} \
  --cloud-provider=${TERRAFORM_PROVIDER} \
  --repo-id=${REPO_ID} \
  --app-dir=path/to/app_dir \
  --config-file-name=path/to/.pipe.yaml
apiVersion: pipecd.dev/v1beta1
kind: TerraformApp
spec:
  input:
    terraformVersion: 1.0.10
    varFiles:
      - path/to/config.tfvars
  triggerPaths:
    - target/path
...

シークレットの管理

シークレットの管理も簡単に行えます。例えばtfファイル内でのGCPのサービスアカウントのファイルを参照したい場合、以下の手順で安全に扱えます。

  1. サービスアカウントのファイルの中身をUIから暗号化します。
  2. 暗号化されたサービスアカウントをPipeCDのアプリケーションコンフィグファイルの spec.encryption.encryptedSecrets.serviceAccount に設定します。
  3. spec.encryption.decryptionTargets にPipedで実行される際に作成される復号化されたサービスアカウントのファイルを置くパスを指定します。
apiVersion: pipecd.dev/v1beta1
kind: TerraformApp
spec:
  input:
    terraformVersion: 1.0.10
    varFiles:
      - path/to/config.tfvars
  triggerPaths:
    - target/path
  encryption:
    encryptedSecrets:
      serviceAccount: {ENCRYPTED_DATA_GENERATED_FROM_WEB}
    decryptionTargets:
      - path/to/decrypted.json
  1. Terraformファイルの中で復号化されたファイルのパスを指定します。
gcp_credentials = "path/to/decrypted.json"

これで設定完了です。詳しくはこちらを参照してください。

terraformコマンドのフラグ

Terraformの init, plan, apply などの各コマンドにフラグを渡したい場合は spec.input.commandFlags.<command> に設定することが可能です。 例えば、以下のような場合です。

apiVersion: pipecd.dev/v1beta1
kind: TerraformApp
spec:
  input:
...
    commandFlags:
      init:
        - "-backend-config=config"
        - "-backend-config=credentials=path/to/credentials"
...

また、全てのコマンドに同じフラグを渡したい場合、spec.input.commandFlags.shared に設定します。 さらに、Terraform実行時に環境変数を設定することもできます。詳しくはこちらを参照してください。

Plan preview

Plan previewとは開発者がコードに変更を加えた際に、各アプリケーションにどのような変更が適用されるのかをデプロイする前に確認できる機能です。これにより、プルリクエスト作成時にフィードバックを受け取り、レビューをより安心して行えるようになります。

Plan previewの動作詳細

実際のシナリオは以下の通りです。

  1. Plan previewジョブはplan-previwを実行して、指定のコミットに対するplan-previewの結果をControl planeに要求します(たいていの場合、CIジョブがmasterとプルリクエストの差分結果を要求します)。要求後、結果をポーリングします。
  2. Control planeは、対象のすべてのpipedをリストアップし、各pipedに対応するコマンド発行します。
  3. Pipedは、Control planeからコマンドを受け取り、プラン・プレビュー結果Control planeに返します。
  4. Plan previewジョブは、結果を受け取り出力します(CIジョブの場合、プルリクエストに結果をコメントします)。

Github Action

Plan previewはpipectlのサブコマンドとして提供されているため、色々な自動化のケースに対応できますが、GithubのプルリクエストでコメントとしてPlan preview結果を確認したいケースに向けて、Github Actionが用意されています。このGithub Actionを使えば、簡単にPlan previwをGithubのプルリクエスト上で実装できます。

まとめ

PipeCDは同じインターフェースでインフラからアプリケーションまで、全てをGitOpsで管理することが可能です。IaaCとしてTerraformを使っている方は、是非試してみてください!