Terraform を使って GCE のインスタンスを作成する

事前準備

API とサービス > 認証情報

認証情報を作成 → サービスアカウントキー
Comupute Engine default service account を選択して JSON 形式で作成する。

Terraform のインストール

brew install terraform

設定ファイルを作成

設定ファイルはベーシックな感じにしてみた。

  • 外部固定IPを使用
  • 80, 443ポートを使用可能
  • プロジェクト全体のSSH認証鍵はブロックして個別に登録
provider "google" {
  credentials = "${file("account.json")}"  // アカウント.jsonが事前準備で用意したJSONファイル
  project     = "xxxxx"
  region      = "asia-northeast1"
}

// ここで記述した値が変数のように扱えるようになる (default の箇所は任意の名前)
// ${google_compute_address.default.name}
resource "google_compute_address" "default" {
  name = "external-network"
}

resource "google_compute_firewall" "allow-http" {
  name    = "default-allow-http"
  network = "default"
  allow {
    protocol = "tcp"
    ports    = ["80"]
  }
  source_ranges = ["0.0.0.0/0"]
  target_tags = ["http-server"]
}

resource "google_compute_firewall" "allow-https" {
  name    = "default-allow-https"
  network = "default"
  allow {
    protocol = "tcp"
    ports    = ["443"]
  }
  source_ranges = ["0.0.0.0/0"]
  target_tags = ["https-server"]
}

resource "google_compute_instance" "default" {
  name          = "xxxxxxx"
  machine_type  = "f1-micro"
  zone          = "asia-northeast1-b"

  // ネットワークタグ
  tags = ["http-server", "https-server"]

  boot_disk {
    // インスタンス削除時にディスクも削除するか
    auto_delete = true

    initialize_params {
      // ベースイメージ(https://cloud.google.com/compute/docs/images#os-compute-support にある プロジェクト/ファミリー で指定)
      image = "debian-cloud/debian-9"
      // ディスクサイズ(GB)
      size = 10
      // ディスクの種類 標準:"pd-standard", SSD:"pd-ssd"
      type = "pd-standard"
    }
  }

  network_interface {
    // ネットワーク
    network = "default"
    access_config {
      nat_ip = "${google_compute_address.default.address}"
      // 未指定の場合はエフェメラルIP。外部IPが不要の場合は access_config 項目自体を削除
    }
  }

  // メタデータ
  metadata {
    // プロジェクト全体のSSH認証鍵をブロック
    block-project-ssh-keys = "true"
    // 個別のSSH認証鍵
    ssh-keys = "user:ssh-ed25519 xxxxxxxxxxxxxxxxxxx user"
  }

  // 起動時に実行するスクリプト
//  metadata_startup_script = "echo hello"

  service_account {
    // サービスアカウントの権限
    // https://cloud.google.com/sdk/gcloud/reference/alpha/compute/instances/set-scopes#--scopes
    // エイリアスまたはスコープURIが指定可能
    scopes = [
      // デフォルト
//      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring.write",
      "https://www.googleapis.com/auth/pubsub",
      "https://www.googleapis.com/auth/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append",
      // カスタム
      "https://www.googleapis.com/auth/sqlservice.admin",
      "https://www.googleapis.com/auth/devstorage.read_write"]
  }

  scheduling {
    // プリエンプティブVMを使用するか
    preemptible = false
    // ホストメンテナンス時にダウンタイムなしにVMインスタンスを移行するか
    on_host_maintenance = true
    // ユーザーの操作以外の理由による自動再起動を行うか
    automatic_restart = true
  }
}

確認

初回時やプロバイダを変えた場合は init コマンドを実行する
.tf ファイルを探して、使用している provider に対応するファイルを .terraform ディレクトリ内に保存するっぽい挙動。

terraform init

plan コマンドで dry run っぽいことができる。

terraform plan

apply コマンドで実際に構築する

terraform apply

destroy コマンドで削除する

terraform destroy