Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
TerraformによるGCP環境の管理

この記事はGoogle Cloud Platform(1) Advent Calendar 2016の3日目となります!

Google Cloud Platform(以下、GCP)のサービスも一部はTokyoにようやくRegionが来たことだし、そろそろ利用してみたいと思った人も多いのではないでしょうか。 今回は、Google Compute Engine(以下、GCE)をTerraformを利用して構成管理をしてみます。

特に意味はないですが、気づいたら文字ばかりだったので、下記に今回利用するサービスのロゴを載せます。

GCP Terraform
gcp terraform

Terraform is 何?という方は、一言で言うと複数のプロバイダ(AWS、GCP、Azure)に対応した構成管理ツールです。 昨今、色々な環境も増えてきて、構成管理をそれぞれのプロバイダのofficial CLIやSDKで行うと辛いという人も増えてきたのではないかと思います。

Terraformは、活動が活発で、各プロパイダのreleaseにも追随して行っています。 Terraformでは設定ファイルを記載するだけなので、今から環境を作ろう、だけどどこにするかまだ決めていないと言った方にもオススメだと思います。曰く、ピボットがしやすいです。

前置きというかTerraform押しが、長くなりましたが、今回は主に下記の2点に絞って環境構築を行います。

  • Terraformでの環境構築onGCP
  • Terraformによる環境のversion管理onGCS

前提条件

Terraformでの環境構築onGCP

まずは、Terraformリソースの配置場所を用意します.

mkdir advent_calendar_1_1203 && cd advent_calendar_1_1203
git init
mkdir Terraform

ここから先はTerraformのtfファイルを作成します。ファイルの中身は一枚にまとめても構いませんが、あまりまとめすぎても可読性が悪いので、下記の例ではリソース種別でファイルを分割しています。

  • gcp_provider.tf
  • gcp_network.tf
  • gcp_firewall.tf
  • gcp_instances.tf

最初にproviderの設定を書きます。今回はGCPを利用します。

# gcp_provider.tf
// Configure the Google Cloud provider
provider "google" {
  credentials = "${file("#{service_account_json_file}")}"
  project     = "mass-gcp-2016-advent-calendar"
  region      = "asia-northeast1"
}

次に、プロジェクトで利用するネットワーク設定を書きます。

# gcp_network.tf
resource "google_compute_network" "gcp-2016-advent-calendar" {
  name = "gcp-2016-advent-calendar"
}
resource "google_compute_subnetwork" "development" {
  name          = "development"
  ip_cidr_range = "10.30.0.0/16"
  network       = "${google_compute_network.gcp-2016-advent-calendar.name}"
  description   = "development"
  region        = "asia-northeast1"
}

次に、firewallのルールを書きます。

# gcp_firewall.tf
resource "google_compute_firewall" "development" {
  name    = "development"
  network = "${google_compute_network.gcp-2016-advent-calendar.name}"

  allow {
    protocol = "icmp"
  }

  allow {
    protocol = "tcp"
    ports    = ["22", "80", "443"]
  }

  target_tags = ["${google_compute_instance.development.tags}"]
}

ここまでくると、プロジェクトの初期設定はほぼできています。 もっとシンプルにデフォルトのネットワークを利用する形もありますが、今回はネットワークもカスタムモードを利用しています。 最後に、この環境にインスタンスを構築します。

# gcp_instances.tf
resource "google_compute_instance" "development" {
  name         = "development"
  machine_type = "n1-standard-1"
  zone         = "asia-northeast1-c"
  description  = "gcp-2016-advent-calendar"
  tags         = ["development", "mass"]

  disk {
    image = "ubuntu-os-cloud/ubuntu-1404-lts"
  }

  // Local SSD disk
  disk {
    type        = "local-ssd"
    scratch     = true
    auto_delete = true
  }

  network_interface {
    access_config {
      // Ephemeral IP
    }

    subnetwork = "${google_compute_subnetwork.development.name}"
  }

  service_account {
    scopes = ["userinfo-email", "compute-ro", "storage-ro", "bigquery", "monitoring"]
  }

  scheduling {
    on_host_maintenance = "MIGRATE"
    automatic_restart   = true
  }
}

ここまで書いたtfファイルをTerraformディレクトリ配下に配置して、planを実行してみます。 Terraformではplanで計画、applyで実行がされます。

terraform plan Terraform

Plan: 4 to add, 0 to change, 0 to destroy. と表示されればplanは成功です。 次にapplyを実行してみます。

terraform apply Terraform

下記のようにcompleteが表示されていれば作成は成功です。

google_compute_firewall.development: Creation complete

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate

試しに構築したインスタンスにログインしてみて、無事インスタンスに入れれば今回の環境構築は終了です。

gcloud compute ssh development --zone asia-northeast1-c

環境のversion管理

今回作成したリソースですが、構成はtfファイルに記載されているものの、applyがどの時点で実行されたかにより環境の状態は変わります。 Terraformではこの状態を管理するためstateファイルといったものを自動でlocal上に作成してくれます。

# terraformを実行したディレクトリ直下にstateファイルが配置されています
find terraform.tfstate
# terraform showでstateの確認を行えます
terraform show

さて、このstateファイルにより環境の状態が管理できますが、この時点ではローカル上にしか存在しない状態です。例えば、これが複数人で環境構築を行い、tfファイルをgithubのリポジトリで管理して、masterに更新が走ったら自動でplan&applyしてくれるようにした場合、最後にapplyした時のstateをどこかで管理したくなると思います。

Terraformではstateをremoteで管理する機能が提供されています。remoteはAWSのS3なども選べますが、今回はGoogle Cloud Storage(以下、GCS)に配置します。GCSに配置することで複数人が環境を触っても、状態を共有することができます。 まず、GCSのbucketを作成します。

# gcp_storage.tf
resource "google_storage_bucket" "gcp-2016-advent-calendar" {
  name          = "gcp-2016-advent-calendar"
  location      = "asia-northeast1"
  storage_class = "STANDARD"
}

resource "google_storage_bucket_acl" "remote-acl" {
  bucket         = "${google_storage_bucket.gcp-2016-advent-calendar.name}"
  predefined_acl = "private"
}

ここで先ほどと同様にterraform plan, terraform applyを実行します。

terraform plan Terraform
terraform apply Terraform

次にリモートの設定を記載します。

# gcp_remote.tf
data "terraform_remote_state" "gcp-2016-advent-calendar" {
  backend = "gcs"

  config {
    bucket = "${google_storage_bucket.gcp-2016-advent-calendar.name}"
    path   = "gcp/terraform.tfstate"
  }
}

最後にremoteの設定を有効化します。この際にterraformが利用するcredentialファイルの情報を環境変数に設定します。

export GOOGLE_CREDENTIALS=#{service_account_json_file}
terraform remote config -backend=gcs -backend-config="bucket=gcp-2016-advent-calendar" -backend-config="path=gcp/terraform.tfstate" -backend-config="project=mass-gcp-2016-advent-calendar"

Remote configuration updated Remote state configured and pulled. と表示されればリモートの設定は成功です。そして今自分の手元にあるstateをremoteにpushしてみます。

terraform remote push

State successfully pushed! と表示されれば、リモートへのpushも成功しています。

終わりに

え、これGoogle Cloud Platform(1) Advent Calendarだよね?TerraformのAdvent Calendar?と思った方がいたら、ごめんなさい。 実際のところGCPとしての新しい機能を試すのではなく、今回は手軽に構築できるツールの紹介もかねてこのような記事となりました。

Terraformのインストール方法や使い方は深くは触れていないので、これはあくまでGoogle Cloud Platform Advent Calendarネタですと言い切ります。 今回作成したリソースの削除は、下記を実行してもらえれば終わります。 プロジェクトやサービスアカウントまでは消えません。あくまでtfファイルで管理しているもののみ消えます。また、GCSにstateファイルがある場合も消えません。

terraform plan -destroy Terraform
terraform destroy Terraform

明日のアドベントカレンダーは、yuichi1004さんです!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.