TerraformでGCPのリソースの作成と変数から値を読み込む

はじめに

今回はTerraformというインフラ環境をコードで定義できるツールについてまとめました。
TerraformはHashCorp社が提供しており、Infrastructure as Code を実現するためのツールです。AWS, GCPなどのクラウド環境はもちろん、ここに記載されているプロバイダーはTerraformで構築することができます。

本記事ではTerrafromが提供しているチュートリアル(GCP)を参考にしています。

Terraformのインストール

まずはじめに、TerrafromはHomebrewでインストールできるので、以下のコマンドでインストールします。

> brew install terraform
> terraform version
Terraform v0.12.9

GCPのセッティング

今回はGoogle Cloud Platformを使用するため、以下の2つのセットアップを済ませておきましょう。

  • GCPプロジェクトの作成
  • Terraform用のサービスアカウントの作成
    1. IAMと管理->サービスアカウント->サービスアカウントの作成へ移動
    2. 適当なサービスアカウント名を入力
    3. 役割をProject->編集者に設定する
    4. キーを作成でキーのタイプをJSONに指定し作成する

Terraformはサービスアカウントを使ってGCPの各リソースにアクセスをおこないます。今回のチュートリアルでは、TerraformのサービスアカウントにProjectの編集者の権限を付与しています。

補足としてサービスアカウントの権限を絞りたい場合は、以下の権限を設定すれば本記事の操作は正常に処理できます。

  • ComputeNetworkの管理者
  • サービスアカウントの管理者

Providerの設定とGCPリソースの定義

TerraformでGCPリソースを操作するために、Googleのproviderの設定をする必要があります。providerの項目には認証用のファイルやプロジェクト名などの情報を記述します。

作成するファイル名はmain.tfとなっており、リソース作成の例としてVPCネットワークに関するコードも追加しています。

provider "google" {
  # サービスアカウントを作成したときにダウンロードしたJSONファイルのパスを指定します
  credentials = file("<NAME>.json")

  project = "<PROJECT_ID>"
  region  = "asia-northeast1"
  zone    = "asia-northeast1-a"
}

# VPCネットワークのリソースを作成する
resource "google_compute_network" "vpc_network" {
    name = "terraform-network"
}

Terraformの初期化

新しくTerraformを使う場合、terraform initで設定を初期化しproviderのpluginなどを追加する必要があります。

> terraform init
Initializing the backend...

Initializing provider plugins...
* provider.google: version = "~> 2.17"

リソースの作成

次にterraform applyでリソースを作成します。作成時に変更前と後の差分が表示され適用するかどうか聞かれるのでyesを入力します。

リソース作成後にローカルのディレクトリをみると.terraform/terraform.tfstateというファイルが作られていることがわかります。これには、Terraformによって作成されたリソースの情報などが保存されています。本記事では紹介しませんが、チームで開発する際にインフラの状態を共有するためには、クラウドのストレージなどにアップロードして管理する必要があります。

> terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
...<中略>
Enter a value: yes
module.network.google_compute_network.network: Creating...
...<中略>
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

GCPコンソールでVPCネットワークが作成されているか確認しましょう。 terraform showでも設定が反映されているかを確認することができます。

> terraform show
# google_compute_network.vpc_network:
resource "google_compute_network" "network" {
    auto_create_subnetworks         = false
    delete_default_routes_on_create = false
    id                              = "terraform-vpc-network"
    name                            = "terraform-vpc-network"
    project                         = "xxxxxx"
    routing_mode                    = "GLOBAL"
    self_link                       = "https://www.googleapis.com/compute/v1/projects/xxxxx/global/networks/terraform-vpc-network"
}

変数を使用して値を読み込む

上記のやり方ではprojectやcredentialsを直にファイルに書き込んでいました。このファイルをGithubなどのバージョン管理システムにアップロードして管理するのはセキュリティ的によくありません。 したがって、秘匿したい変数を外部のファイルやコマンドライン引数から読み込むこととします。

変数を定義する

準備としてmain.tfに直接書き込んでいたパラメータで変数に置き換えたいものを variables.tf に記載します。
regionzoneはデフォルト値を指定していますが、projectcredentials_fileは後述する別ファイルまたはコマンドライン引数などから読み込むため空になっています。

variable "project" {}

variable "credentials_file" {}

variable "region" {
  default = "asia-northeast1"
}

variable "zone" {
  default = "asia-northeast1-b"
}

main.tf ファイルで変数を使用する

次にmain.tfに直接書き込んでいたパラメータを変数に置き換えます。変数は var.<変数名> のように指定します。

provider "google" {
  credentials = file(var.credentials_file)

  project = var.project
  region  = var.region
  zone    = var.zone
}

コマンドライン引数から読み込む

-varオプションで変数の組を引数に渡すことで読み込むことができます。

> terraform plan -var 'project=<PROJECT_ID>' -var 'credentials_file=<NAME>.json'

ファイルから読み込む

ファイルから変数を読み込むためにはterraform.tfvarsか接尾辞が.auto.tfvarsのファイルを作成します。作成後にterraform applyをすると自動で変数を読み込んでくれます。

project          = "<PROJECT_ID>"
credentials_file = "<NAME>.json"

terraform planterrafom applyの実行時に-var-flieオプションを使用した場合は先述のファイル名である必要はありません。コマンドライン引数でsecret.tfvarsdevelopment.txtなどを指定することで変数を読み込むことができます。

> terraform plan -var-file="secret.tfvars"

環境変数から読み込む

変数をマシンの環境変数から読み込みたい場合は、環境変数TF_VAR_<変数名>を設定します。 今回の場合は以下の2つを追加すれば大丈夫です。

  • TF_VAR_project="<PROJECT_ID>"
  • TF_VAR_credentials_file="<NAME>.json"

注意として、環境変数を使用する場合はstring型しか設定することができません。
Lists型やMaps型などは使用できないので、これらが必要な場合はファイルかコマンドライン引数で読み込むようにしてください。

リソースの削除

リソースを作成したままにしてしまうと課金されてしまう場合があるので削除しておきましょう。
作成したリソースを削除するためにはterraform destroyコマンドを使用します。削除するリソース内容と、削除するかを聞かれるのでyesと入力すれば環境を削除することができます。

> terraform destroy
<削除するリソース内容>

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

まとめ

今回は、Terraformでのリソース作成と変数をファイルなどから読み込む設定を行いました。

チュートリアルには、Google Compute Engineの作成や、チームでTerraformを使う際のやり方が記載されています。また、疑問に思ったことがあればTerraformのドキュメントに大体書いてあるのでサクサク試すことができました。

個人のプロジェクトでTerraformを使うかどうか迷っていまいしたが、環境の作成・変更・削除をコードで簡単にできるのは良いと感じました。実際に使ってみて知見があれば記事を書こうと思います!

参考文献

learn.hashicorp.com

www.terraform.io