☁️

【Terraform】Docker で VS Code の Dev Container 上に快適な Google Cloud 環境を構築する

2024/12/17に公開
2

0. はじめに

株式会社ディー・エヌ・エーに入社し,MLOps エンジニアをやっている @a5chin です.
本記事では図 1 の様に Docker を使って VS Code の Dev Container 上に Terraform[1] + Google Cloud[2] の開発環境を作成することを目指します.

format
図 1: Dev Container 上で開発をすると自動フォーマット[3]と pre-commit が走る

https://github.com/a5chin/terraform-template/tree/main

CI/CD が入っていたりと,本記事で解説する内容よりもリッチな設定が以下のリポジトリに置いてあるので,ぜひ使って頂けたらと思います.
PR も大歓迎です!

0.1. 事前準備

本記事で作成したリポジトリを動かすためには,Docker Desktop と VS Code のダウンロード,VS Code 上で Dev Container のインストールが必要です.
また,以下コマンドでリポジトリを clone すると,今後進めやすくなるので clone することをおすすめします.

git clone https://github.com/a5chin/terraform-template

0.1.1. Docker Desktop のダウンロード

https://www.docker.com/ja-jp/products/docker-desktop/

上記リンクからお使いの OS に合った Docker Desktop をダウンロードしてください↑

Docker Desktop は Mac や Windows に簡単にインストールできるアプリケーションです.
これにより,コンテナ化アプリケーションやマイクロサービスを構築し共有することができます.

0.1.2. VS Code のダウンロード

https://code.visualstudio.com/download

上記リンクからお使いの OS に合った VS Code をダウンロードしてください↑

VS Code は Microsoft 社から無償で提供されており,Windows, macOS, および Linux で使用できる,軽量ながら強力なソースコードエディターです.
拡張機能によって,全体的な機能に加えてさらに機能を追加することでより快適に開発することができます.

0.1.3. Dev Container のインストール

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers

VS Code 上で VS Code の拡張機能である,Dev Container をインストールしてください.
VS Code 上で⇧⌘xと入力すると,サイドに Extensions が開くのでms-vscode-remote.remote-containersと入力して,出てきた拡張機能をインストールしてください.

Dev Container は Microsoft が開発している VS Code の拡張機能です.
Dev Container を使うことで,VS Code から Docker コンテナを開発環境として使用できます.

1. 結論

https://github.com/a5chin/terraform-template/tree/main

Step Save commit GitHub Actions
Terraform Format
Terraform Linter
Docker Linter (Hadolint)
Terraform Test
Docker Build

上記対応表の様に,私が設定した Dev Countainer 上で開発をすることによって,Format[3:1], Lint[4], Test[5], Build[6] を自動化しています.

1.1. 実際の操作画面

Terraform[1:2] で記述したコードを保存して,git で commit した時の操作画面です.

format
図 2: Dev Container 上で開発をすると terraform fmt による自動フォーマット[3:2]と pre-commit が走る

2. Docker で開発環境を整える

以下では,主に Docker について解説していきます.
Dev Container は Docker コンテナを開発環境として作成するからです.

以下のフローで Terraform[1:3] + Google Cloud[2:1] の環境を作成します.

  1. tfenv を使えるようにし
  2. Cloud SDK を使えるようにする

2.1. tfenv を使えるようにする

最新の tfenv リポジトリをクローンして Path を通すことで,使えるようになります.

.devcontainer/Dockerfile
  FROM mcr.microsoft.com/vscode/devcontainers/python:3-boolworm


+ RUN git clone --depth=1 https://github.com/tfutils/tfenv.git /opt/tfenv

+ ENV PATH=$PATH:/opt/tfenv/bin

2.2. 自動フォーマット

次に,保存時に自動でフォーマットがかかる様に設定します.
そのためには,VS Code の拡張機能として hashicorp.terraform をインストールする必要があります.
そして,.vscode/settings.json に保存時にフォーマットされる様に設定を書きます.

2.2.1. 拡張機能: hashicorp.terraform

VS Code の拡張機能である hashicorp.terraform をインストールします.
この拡張機能で以下が可能になります.機能詳細は以下のリンクを参照してください.

  • IntelliSense
  • Syntax validation
  • Syntax highlighting
  • Code Navigation
  • Code Formatting
  • Code Snippets
  • HCP Terraform Integration
  • Terraform Module Explorer
  • Terraform commands

https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform

.devcontainer/devcontainer.json
{
    "name": "Terraform",
    "build": {
        "context": "..",
        "dockerfile": "Dockerfile",
    },
    "customizations": {
        "vscode": {
            "extensions": [
+               "hashicorp.terraform",
            ]
        }
    },
    "remoteUser": "vscode"
}

2.2.2. Formatter の設定

次に,インストールした hashicorp.terraform で保存時にフォーマットができるように以下の様に設定を記述します.

.vscode/settings.json
{
    "files.insertFinalNewline": true,
    "files.trimTrailingWhitespace": true,
    "terminal.integrated.defaultProfile.linux": "zsh",
    "terminal.integrated.profiles.linux": {
        "zsh": {
            "path": "/bin/zsh"
        }
    },
+   "[terraform]": {
+       "editor.defaultFormatter": "hashicorp.terraform",
+       "editor.formatOnSave": true,
+       "editor.formatOnSaveMode": "file",
+       "editor.tabSize": 2
+   },
+   "[terraform-test]": {
+       "editor.defaultFormatter": "hashicorp.terraform",
+       "editor.formatOnSave": true,
+       "editor.formatOnSaveMode": "file",
+       "editor.tabSize": 2
+   },
+   "[terraform-vars]": {
+       "editor.defaultFormatter": "hashicorp.terraform",
+       "editor.formatOnSave": true,
+       "editor.formatOnSaveMode": "file",
+       "editor.tabSize": 2
+   }
}

2.3.2. pre-commit の設定

pre-commit とは,文字通り git コマンドでコミットする前の行動を指定することができます.
今回は以下を commit 前に走らせるように設定します.

  • Docker
    • lint(hadolint)
  • Terraform
    • docs
    • format
    • lint
.devcontainer/devcontainer.json
  {
      "name": "Terraform",
      "build": {
          "context": "..",
          "dockerfile": "Dockerfile",
      },
      "features": {
+         "ghcr.io/devcontainers-extra/features/pre-commit:2": {},
+         "ghcr.io/devcontainers-extra/features/terraform-docs:1": {},
+         "ghcr.io/dhoeric/features/hadolint:1": {}
      },
      "customizations": {
          "vscode": {
              "extensions": [
+                 "exiasr.hadolint",
+                 "hashicorp.terraform",
              ]
          }
      },
+     "postCreateCommand": "pre-commit install",
      "remoteUser": "vscode"
  }
.pre-commit.yaml
default_stages: [pre-commit]

repos:
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: "v1.96.1"
    hooks:
      - id: terraform_docs
        name: terraform-docs
        description: "Run terraform-docs"

      - id: terraform_fmt
        name: terraform-fmt
        description: "Run 'terraform fmt' for format"
        args: [recursive]

      - id: terraform_tflint
        name: terraform-lint
        description: "Run tflint"

2.3. Cloud SDK を使えるようにする

今回は私が普段使っている Google Cloud[2:2] を Dev Container 上で使える様にします.
概要としては Cloud SDK のインストーラーをダウンロードして,Path を通しているだけです.
インストーラーのダウンロードに Cloud SDK のバージョン指定とプラットフォームの指定が必要なため,分岐をしています.

.devcontainer/Dockerfile
  FROM mcr.microsoft.com/vscode/devcontainers/python:3-boolworm

+ RUN if [ "$(uname -m)" = 'aarch64' ]; then _ARCH=arm; else _ARCH=x86_64; fi \
+     && curl -fsS "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-502.0.0-linux-$_ARCH.tar.gz" \
+     | tar zx -C /opt \
+     && /opt/google-cloud-sdk/install.sh \
+     --quiet \
+     --usage-reporting=false \
+     --additional-components alpha beta

  RUN git clone --depth=1 https://github.com/tfutils/tfenv.git /opt/tfenv

+ ENV PATH=$PATH:/opt/google-cloud-sdk/bin
  ENV PATH=$PATH:/opt/tfenv/bin

2.4. ARG を用いる

ARGDockerfile 内で使用できる変数で,変数の値によって生成するイメージの中身を変えることが可能です.
破壊的な変更を避ける目的で,バージョンを固定します.

.devcontainer/Dockerfile
+ ARG BASE_IMAGE=mcr.microsoft.com/vscode/devcontainers/python
+ ARG DEBIAN_VERSION=bookworm
+ ARG PYTHON_VERSION=3.12


+ FROM $BASE_IMAGE:$PYTHON_VERSION-$DEBIAN_VERSION
  LABEL maintainer="a5chin <a5chin.origin+contact@gmain.com>"

+ ARG GCLOUD_SDK_VERSION=502.0.0
+ ARG TFENV_VERSION=v3.0.0

  SHELL [ "/bin/bash", "-o", "pipefail", "-c" ]

  RUN if [ "$(uname -m)" = 'aarch64' ]; then _ARCH=arm; else _ARCH=x86_64; fi \
+     && curl -fsS "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/  google-cloud-cli-$GCLOUD_SDK_VERSION-linux-$_ARCH.tar.gz" \
      | tar zx -C /opt \
      && /opt/google-cloud-sdk/install.sh \
      --quiet \
      --usage-reporting=false \
      --additional-components alpha beta

+ RUN git clone --depth=1 -b $TFENV_VERSION https://github.com/tfutils/tfenv.git /opt/tfenv

  ENV PATH=$PATH:/opt/google-cloud-sdk/bin
  ENV PATH=$PATH:/opt/tfenv/bin
.devcontainer/devcontainer.json
  {
      "name": "Terraform",
      "build": {
          "context": "..",
          "dockerfile": "Dockerfile",
          "args": {
+             "BASE_IMAGE": "mcr.microsoft.com/vscode/devcontainers/python",
+             "DEBIAN_VERSION": "bookworm",
+             "GCLOUD_SDK_VERSION": "502.0.0",
+             "PYTHON_VERSION": "3.12",
+             "TFENV_VERSION": "v3.0.0",
          }
      },
      "features": {
          "ghcr.io/devcontainers-extra/features/pre-commit:2": {},
          "ghcr.io/devcontainers-extra/features/terraform-docs:1": {},
          "ghcr.io/dhoeric/features/hadolint:1": {}
      },
      "customizations": {
          "vscode": {
              "extensions": [
                  "aquasecurityofficial.trivy-vulnerability-scanner",
                  "exiasr.hadolint",
                  "hashicorp.terraform",
                  "mosapride.zenkaku",
                  "ms-azuretools.vscode-docker",
                  "redhat.vscode-yaml",
                  "shardulm94.trailing-spaces"
              ]
          }
      },
      "postCreateCommand": "pre-commit install",
      "remoteUser": "vscode"
  }

3. まとめ

本記事では,VS Code の Dev Container 上に快適な Terraform[1:4] 環境を構築する方法について解説しました.
よりリッチな設定が以下のリポジトリにあるので,ぜひ使ってください!(PR も歓迎です)
皆さんが快適な Terraform[1:5] ライフを送れることを願います💫

https://github.com/a5chin/terraform-template/tree/main

脚注
  1. Terraform は IaC と呼ばれるツールの一種で,インフラの構成をソースコードとして管理できる機能です. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  2. Google が提供するクラウドサービスのひとつで,Google が自社で使用している同じインフラを利用者に提供しているため,スケーラビリティの高いリソースを簡単に利用可能です. ↩︎ ↩︎ ↩︎

  3. 一貫性のあるコーディングスタイルを強制させることです. ↩︎ ↩︎ ↩︎

  4. 潜在的なバグや不適切なコーディングスタイルを検出し,それらを修正することでコードの品質を向上できます. ↩︎

  5. コードの機能をテストし,期待通りに動作することを確認することです. ↩︎

  6. Docker イメージを構築することを指します.イメージからコンテナを作成することができます. ↩︎

GitHubで編集を提案
DeNA Engineers

Discussion

arrowkatoarrowkato

細かいところですが、

図 2: Dev Container 上で開発をすると Ruff による自動フォーマット

こちら、Ruffではなくて、terraform fmt ではないでしょうか?

a5china5chin

ご指摘の通りです!ありがとうございます!
修正いたしました🙇