この記事はGoogle Cloud Platform(1) Advent Calendar 2016の3日目となります!
Google Cloud Platform(以下、GCP)のサービスも一部はTokyoにようやくRegionが来たことだし、そろそろ利用してみたいと思った人も多いのではないでしょうか。 今回は、Google Compute Engine(以下、GCE)をTerraformを利用して構成管理をしてみます。
特に意味はないですが、気づいたら文字ばかりだったので、下記に今回利用するサービスのロゴを載せます。
GCP | Terraform |
---|---|
Terraform is 何?という方は、一言で言うと複数のプロバイダ(AWS、GCP、Azure)に対応した構成管理ツールです。 昨今、色々な環境も増えてきて、構成管理をそれぞれのプロバイダのofficial CLIやSDKで行うと辛いという人も増えてきたのではないかと思います。
Terraformは、活動が活発で、各プロパイダのreleaseにも追随して行っています。 Terraformでは設定ファイルを記載するだけなので、今から環境を作ろう、だけどどこにするかまだ決めていないと言った方にもオススメだと思います。曰く、ピボットがしやすいです。
前置きというかTerraform押しが、長くなりましたが、今回は主に下記の2点に絞って環境構築を行います。
- Terraformでの環境構築onGCP
- Terraformによる環境のversion管理onGCS
- Terraformをinstallしておいてください。
- GCP側のプロジェクトは事前に用意しておいてください。
- GCP側のプロジェクトではCompute EngineのAPIを有効にしておいてください。
- プロジェクトののサービスアカウントのcredentialファイル(JSON形式)も用意しておいてください。(なお、今回のサービスアカウントはprojectのowner権限を付与しています。テスト用プロジェクトなので雑にしていますが、もっと権限を縛ることもできますので、適時調整してください。)
まずは、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
今回作成したリソースですが、構成は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さんです!