🐙

Terraform, gcloudを使ってVMインスタンス立ち上げまでやってみる

2024/01/24に公開

4ステップでやっていきます。

  1. gcloudの導入
  2. gcloudの初期設定
  3. gcloudでterraformに必要な情報等の作成や取得
  4. terraformの設定から実行(VMインスタンスの立ち上げ)

gcloudの導入

パッケージ更新

sudo apt update && sudo apt upgrade

リポジトリの追加

echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list

Google Cloudの公開鍵の追加

curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -

パッケージリストの更新

sudo apt update

Google Cloud SDKのインストール

sudo apt install google-cloud-sdk

gcloudの初期設定

gcloudの初期化

gcloud init

gcloudの認証

gcloud auth login

自分はWSL環境でやっていたのですが、どうもlocalhostにつなげるとうまくいきませんでした。表示されたurlをブラウザに張り付けて認証をすることでうまく動作しました。

gcloudでterraformに必要な情報等の作成や取得

プロジェクトの作成

gcloud projects create <プロジェクトID> --name=<プロジェクト名>

すでにあるプロジェクトを使いたい場合は、後述しますがgcloud config listを利用してプロジェクトIDを取得してください。

プロジェクトの設定

gcloud config set project <プロジェクトID>

gcloudにプロジェクトの紐付けを上記コマンドで行います。

プロジェクトの確認

gcloud config list

VMインスタンスAPIの有効化

gcloud services enable compute.googleapis.com --project <プロジェクトID>

自分がやった限りですが進捗表示がされず、また時間が1分程度はかかった印象なので「あれ?ちゃんと動いてるのか?」ってなったりしました。

有効なAPIの確認

gcloud services list --enabled --project <プロジェクトID>

請求アカウントのリンク

gcloud beta billing accounts list

上記コマンドで請求アカウントのリストを確認できます。

gcloud beta billing projects link [PROJECT_ID] --billing-account=[BILLING_ACCOUNT_ID]

上記コマンドでリンクさせます。

サービスアカウントの作成

gcloud iam service-accounts create [SERVICE_ACCOUNT_NAME] --display-name [DISPLAY_NAME]

変数部分にはどちらも任意の名前を付けます。

サービスアカウントの確認

gcloud iam service-accounts list

サービスアカウントに権限の付与

gcloud projects add-iam-policy-binding [PROJECT_ID] --member="serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" --role="roles/compute.admin"

roles/compute.adminを付与することでvmインスタンスの操作ができるようになります。

サービスアカウントの権限の確認

gcloud projects get-iam-policy [PROJECT_ID] --flatten="bindings[].members" --format='table(bindings.role)' --filter="bindings.members:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com"

サービスアカウントキーの作成

gcloud iam service-accounts keys create [FILE_NAME].json --iam-account [SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com

terraformの設定から実行

今回環境はDockerを利用して作成します。
以下に簡易的なDockerfile, docker-compose.ymlのコードを置いときます。

Dockerfile
FROM hashicorp/terraform:1.7.0
WORKDIR /workspace
docker-compose.yml
version: '3.9'
services:
  terraform:
    build: .
    volumes:
      - ./workspace:/workspace
    env_file:
     - .env

.envファイルの作成

.env
TF_VAR_credentials=キーファイル名
TF_VAR_region=リージョン(us-central1など)
TF_VAR_project=プロジェクトID
TF_VAR_zone=ゾーン(us-central1-aなど)
TF_VAR_instance=インスタンス名
TF_VAR_instance_name_prefix=インスタンス名のプレフィックス
TF_VAR_instance_count=インスタンス数

上記サンプルを参考に.envファイルを作成します。

main.tfの作成

main.tf
provider "google" {
  credentials = file(var.credentials)
  project     = var.project
  region      = var.region
}

resource "google_compute_instance" "single" {
  name         = var.instance
  machine_type = "e2-micro"
  zone         = var.zone

  boot_disk {
    initialize_params {
      image = "ubuntu-2204-lts"
    }
  }

  network_interface {
    network = "default"
    access_config {
      // Ephemeral IP
    }
  }
}

resource "google_compute_instance" "multiple" {
  count        = var.instance_count
  name         = "${var.instance_name_prefix}-${count.index + 1}"
  machine_type = "e2-micro"
  zone         = var.zone

  boot_disk {
    initialize_params {
      image = "ubuntu-2204-lts"
    }
  }

  network_interface {
    network = "default"
    access_config {
      // Ephemeral IP
    }
  }
}

variable "credentials" {
  description = "Path to the JSON file used to describe your account credentials"
}

variable "project" {
  description = "The ID of the project in which the resources belong"
}

variable "region" {
  description = "The region in which to create the resources"
}

variable "zone" {
  description = "The zone in which to create the resources"
}

variable "instance" {
  description = "The name of the single instance to create"
}

variable "instance_count" {
  description = "The number of instances to create"
  default     = 1
}

variable "instance_name_prefix" {
  description = "The prefix for the instance names"
  default     = "instance"
}

こんな感じで作成します。
main.tfはrootにworkspaceディレクトリを作成し、その中に作成する想定です。

variableで設定されているものにはさきほど.envファイルで作成してTF_VAR_*のアスタリスク部分に合致するものが入ってきます。

サービスアカウントキーの配置

gcloudで作成したサービスアカウントキーはworkspaceディレクトリ内に配置しておきます。
.envファイルのTF_VAR_credentialsには、そのキーファイル名を入力する形です。

terraformの初期化

docker compose run --rm terraform init

terraform init は、Terraformプロジェクトを初期化します。プラグインやプロバイダーなどの必要なコンポーネントをダウンロードし、Terraformがプロジェクトを実行する準備を整えます。
※--rmはコンテナの終了時にコンテナを削除するオプションです。

terraformのプラン

docker compose run --rm terraform plan

実行するとリソースの作成や変更前との差分をプレビューできます。

terraformの実行

docker compose run --rm terraform apply

実際にリソースを作成します。
もし例として挙げたmain.tfと同じものを使用した場合はvmインスタンスが3つ作成されるはずです。

terraformの破棄

docker compose run --rm terraform destroy

terraformによって管理されているすべてのインフラストラクチャーが破棄されます。
今回のケースだと作成したvmインスタンスが削除されます。


今回の記事の内容について、筆者がterraform練習用にまとめたものでgithubリポジトリのほうにもあります。構成がわかりにくかったりした場合そちらも確認してみてください。

https://github.com/torohash/terraform-practice

あとYoutubeでちょくちょくライブコーディングの配信をしてたりします。あんまりいないと思いますが、もし興味あったりする人いたら気軽に見てもらえたら嬉しいです(宣伝)

https://www.youtube.com/@torohash

Discussion