🎃

devcontainerで構築するTerraformとgcloud CLIの実行環境

2023/12/20に公開

1. はじめに

筆者はインフラの学習・実験のために個人でGCPアカウントを用意しています。あくまで学習目的のアカウントなので、構築したインフラリソースによってお金がかかりすぎないように、リソースは全てTerraformで管理しています。学習の都度、リソースをTerraformでチャチャっと作成し、満足したらササっと削除する感じで運用しています。

この記事では、上記の目的でTerraformとgcloudコマンドを実行するべく構築したdevcontainerについて紹介します。今回はGCPを使う前提でのdevcontainer構築方法を紹介しますが、少し変更するだけでaws cliの実行環境にもなるはずです。ですので、AWS利用者にとっても環境構築のヒントになれば幸いです!

2. 要点

dev container自体については基本的な知識があることを前提にします。その上で、今回の環境構築の要点は以下2点です。

  1. devcontainerのベースイメージには、公式が開発しているものを利用すること
  2. dev container featuresを利用すること

まずは、devcontainerのベースイメージについてです。私はdevcontainer用のベースイメージとしてmcr.microsoft.com/devcontainers/base:debianを利用しています。このような公式イメージを利用すると、次に説明するdev container featuresも利用しやすくて便利です。

次に、dev container featuresについてです。これは、devcontainerにツールを簡単に追加するための機能です。従来、devcontainerにツールを追加する際は、Dockerfileにツールをインストールするスクリプトを記述していました。ですが、この機能のおかげでその必要がほとんどなくなり、devcontainer用のDockerfileがスッキリ書けるようになりました。基本的な使い方などは、他にわかりやすい記事がたくさんある(こちらの記事など)ので、詳細は割愛します。dev container featuresが用意されていないツールのみ、Dockerfile内でインストールするスクリプトを記述します。

3. 筆者の設定

筆者の設定を晒します。ここに記載した内容をコピペすれば大体うまくいくはずです!
ただし、これが完璧な設定という訳ではありません。現状の設定で筆者の目的は達成しているので、これ以上の深掘りをしていません。もしかしたらもっと良い設定方法があるかもしれません。ですので、より良い設定方法をご存知の方がいらっしゃいましたら、ぜひ教えていただけると嬉しいです!

3-1. ディレクトリ構成

.
└── .devcontainer
    ├── devcontainer.json
    ├── docker-compose.yml
    └── Dockerfile

3-2. 各種ファイルの中身

まずはdocker-compose.ymlです。
devcontainerはずっと起動させたいので、command: sleep infinityとしています[1]

.devcontainer/docker-compose.yml
version: "3.9"
services:
  tfdev:
    build:
      context: "."
    command: sleep infinity
    volumes:
      - ../:/workspace/mytf

続いて、Dockerfileです。現時点では、gcloud CLI用のdev container featuresは用意されていないので、インストールスクリプトをDockerfileに記述しています。

.devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/base:debian

RUN apt-get update && \
    apt-get install -y \
      apt-transport-https \
      ca-certificates \
      curl \
      gnupg

# Install gcloud
# [ref] https://cloud.google.com/sdk/docs/install?hl=ja#deb
RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
RUN apt-get update && \
    apt-get install -y \
      google-cloud-cli \
      google-cloud-sdk-gke-gcloud-auth-plugin

最後に、devcontainer.jsonです。Terraform周りのツールは用意されているdev container featuresを利用してdevcontainerにインストールしています。また、GKEを構築して、kubectlhelmコマンドも叩きたいので、Kubernetes周りのツールもdev container featuresを通してインストールしています。そして、pre-commitもインストールしています。ここまで触れていませんでしたが、筆者はpre-commitフックでterraform fmttflintterraform-docsを実行するように設定しているからです。

また、postCreateCommandとしてgcloud init --no-launch-browsergcloud auth application-default loginの両方を実行するのもポイントです。gcloud initコマンドは、gcloud CLIを初期化してgcloudコマンドを実行可能にするために必要です。一方で、gcloud auth application-default loginアプリケーションのデフォルト認証情報(ADC)にユーザー認証情報を提供するために必要です。TerraformはADCを利用してGCPにアクセストークンをリクエストするため、ADCに認証情報を提供しておく必要があるのです。

.devcontainer/devcontainer.json
{
  "name": "Terraform",
  "dockerComposeFile": [
    "./docker-compose.yml"
  ],
  "service": "tfdev",
  "runServices": [
    "tfdev"
  ],
  "workspaceFolder": "/workspace/mytf",
  "postCreateCommand": "git config --local credential.helper 'cache --timeout=86400' && pre-commit install && gcloud init --no-launch-browser && gcloud auth application-default login",
  "features": {
    "terraform": {
      "version": "1.6.5",
      "tflint": "latest",
      "terragrunt": "latest"
    },
    "ghcr.io/dhoeric/features/terraform-docs:1": {},
    "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {
      "version": "1.28.0",
      "helm": "latest",
      "minikube": "latest"
    },
    "ghcr.io/devcontainers-contrib/features/pre-commit:2": {}
  },
  "customizations": {
    "vscode": {
      "settings": {
        "terminal.integrated.defaultProfile.linux": "zsh",
        "terminal.integrated.profiles.linux": {
          "zsh": {
            "path": "/usr/bin/zsh"
          }
        }
      },
      "extensions": [
        "eamodio.gitlens",
        "editorconfig.editorconfig",
        "mhutchie.git-graph",
        "github.copilot",
        "streetsidesoftware.code-spell-checker",
        "ms-vsliveshare.vsliveshare",
        "HashiCorp.terraform"
      ]
    }
  }
}

4. まとめ

この記事では、Terraformとgcloud CLIの実行環境をdevcontainerで構築する方法を紹介しました。個人用に構築した環境ですが、チーム開発用の環境としてもヒントになるものがあるかもしれません。どこかで誰かの助けになれば幸いです。

脚注
  1. ちなみに、sleepコマンドの機能というわけではないようです。 ↩︎

Discussion