[ GCP ] 知識ゼロから Terraform を使って GCP 上のリソースを管理してみる!

[ GCP ] 知識ゼロから Terraform を使って GCP 上のリソースを管理してみる!

こんばんは、七色メガネです。

今日は Terraform を使って GCP 上のリソースを管理する方法を学んでいきます。

そも Terraform ってなに?

Terraform (テラフォーム)とは、HashiCorp 社によってオープンソースとして公開されているインフラストラクチャの管理ツールです。

従来インフラストラクチャの構成・管理という分野は、例えば作業者が「作業手順書」に従って一つずつコマンドを実行しなくてはいけなかったり、また時には作業者の独断で各種パラメータが設定されたり(特に小規模なプロジェクトにおいて)など、兎にも角にも可視化されづらく、そして可視化されていても管理コストのかかるものでした。

そんな問題を解決するために生み出されたのが、Terraform です。
Terraform は「安全に、かつ効率的に、インフラストラクチャの構成、変更、バージョン管理を行えるようにする (公式より)」ことを目的としたツールです。
Terraform ではインフラリソースを宣言的に定義して構成を実行することができ、かつそれをコードとして管理することができるため、煩雑な作業手順に悩まされることなく対象のリソース構成だけに集中することができ、かつ変更履歴管理も容易に行えるという優れものです。

https://www.terraform.io/intro/index.html

Terraform を使ってみる!

では前置きは早々に切り上げて、早速 Terraform を使ってみましょう!
今回は以下の手順で作業を進めていきます。

  1. 作業前提の確認
  2. GCP プロジェクト側で Terraform を使うための準備をする
  3. Terraform の準備をする
  4. Terraform で GCP プロジェクトに GCS のバケットを作ってみる

作業前提の確認

今回作業するに当たって、以下の前提が必要になります。

・インフラストラクチャの管理が行われる GCP プロジェクトが存在している
・作業 PC に Cloud SDK が導入されており、gcloud コマンドが実行できる。
・ローカルに作業用のディレクトリがある。(中身は空で良い)

もし自由にできるプロジェクトが存在していなかったり SDK が入っていない場合、ここから先に進む前に予め準備しておきましょう。

GCP プロジェクト側で Terraform を使うための準備をする

ではまず GCP 側で、Terraform を使う準備を行いたいと思います。必要な準備は次の3つです。

  1. Terraform 用のサービスアカウントを作成する
  2. Terraform 用のサービスアカウントにリソース管理のための権限を付与する
  3. サービスアカウントのキーを取得する

全てサービスアカウント(以下、SA ) 関連ですね。Terraform での操作は全て SA 経由で行うため、予め準備しておきましょう。

サービスアカウントを作成する

まずはサービスアカウントの作成です。コンソール画面からでも作成できますが、今回は gcloud コマンドベースで進めたいと思います。下記のコマンドを実行しましょう。

成功していれば、コンソールから SA の存在を確認できます。(確認しなくても良いですが)

サービスアカウントに権限を付与する

次にこの SA に  権限 (IAM) を設定しましょう。本来であればミニマムな IAM ロールを付与すべきですが、今回はテストなので「プロジェクト編集者」という強い権限を付与してしまいましょう。コマンドは次の通りです。

成功すると、コンソールの IAM から以下のように確認ができるはずです。

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

最後に、ローカルからこの SA を使用するため、 SA の json キーを発行します。保存場所は、作業ディレクトリ直下の credential/account.json とします。(どこでもいいですが)
以下のコマンドを実行しましょう。

無事にキーが作成・ 保存されていれば GCP 側の設定は終了です。最後に key の位置を export しておきましょう。

これでローカルから Terraform を実行した時、この SA を介してこのプロジェクトに対してアクションされます。

Terraform の準備をする

ではここからは、ローカルで Terraform の準備をしていきましょう。

Terraform をインストールする

まずは Terraform のインストールからですね。今回は brew を使います。下記のコマンドを実行してください。

成功確認のため、インストールが終わったらバージョンを確認してみましょう。正常にバージョンが表示できていれば問題ありません。

tf ファイルを作成する

次に .tf ファイルを作成します。terraform でのリソース宣言は、全てこの tf ファイル中で行われます。

この tf ファイルは後ほど追記していくのですが、まずは terraform の初期化のために tf ファイルを用意するのがここでの目的なので、まずは main.tf という名前で、以下のような簡易的な構成にて作成しましょう。各項目の意味は後ほど説明します。

Terraform ワークスペースを初期化する

basic な main.tf を作成したら、ワークスペースの作成準備が整いました。main.tf を配置した回想にて、以下のコマンドを実行して初期化を実行しましょう。

成功すると以下のようなログが流れ、.terraform という隠しファイルが作成されます。それが確認できたら、Terraform の準備は完了です。

Terraform で GCP プロジェクトに GCS のバケットを作ってみる

ここまでで GCP 側の準備と、Terraform を利用する準備が整いました。説明されていないおまじない的な書き方が散見されますが、とりあえずはリソース作成まで進んでみましょう!

ここでは次の2つの操作を行って、GCP プロジェクト上に GCS のバケットを作成するというアクションをしてみたいと思います。

  1. main.tf に GCS バケットを定義する
  2. GCP プロジェクト上に GCS バケットを作成する

main.tf に GCS バケットの定義を記述する

まずは tf ファイルに、バケットの定義を追記しましょう。
記述内容は後ほど解説しますので、一旦はこの通りに記述してみてください。とはいえ、雰囲気はなんとなくわかると思います。”terraform_test_0802″ という名前のバケットを、クラス: “Regional” で作ってください、という宣言ですね。

実行計画を確認する

さてリソース作成の前に、「今回の操作によってどのようなリソース変更が実行されるか」ということを確認しましょう。実行計画確認のための以下のコマンドを実行してみてください。同名のバケットが存在していない限り、次のようなログが出るはずです。

まずここで注目したいのは2点、作成されるリソースの構成と、実行されるアクションの種類ですね。

今回は作成するバケットについて名前とクラスしか指定していないため、それだけの情報を持ったバケットが作成されますよということが表示されています。

また、今回は新規作成が1件であること、更新や削除は伴わないことも情報として表示されています。事前に plan しておくことで、予期せぬ操作ミスを防ぐことができますね。

リソースを作成する

では実行計画も確認しましたし、定義した内容で実際にリソースを作成してみましょう!

操作は簡単、以下のコマンドを実行するだけです。

この時、最終確認としてもう実行計画が表示されます。内容に問題がなければ、yes をコンソール上で入力しましょう。

成功すると、次のようなログが流れます。実際にコンソールで GCS を確認してみても、期待した通りのバケットが作成されたことが確認されます。

最初の準備こそ少し必要ですが、目的のリソース管理のための記述は数行で行えるということを考えると、確かにこれはとても便利ですよね。

Terraform のコマンドや文法を学ぶ!

さて、ここで一度足を止めて Terraform のコマンドや文法を学んでみましょう。特に文法はリソース毎に書き方が異なるので基本的には常に公式 doc を参照することになるものの、どういったものがあって何を規定していくのか、という初歩の知識をここで確認していきましょう。

Terraform のコマンド

Terraform で使用できる主なコマンドには次のようなものがあります。

init

terraform init コマンドを実行すると、作業ディレクトリが初期化されます。
初めて terraform での作業を開始するときはもちろん、後述する state ファイルの保存場所を更新するときなどにも使用します。

fmt

terraform fmt コマンドを実行すると、カレントディレクトリに存在する tf ファイルに対してフォーマッティングを実行してくれます。構成の変更時や git への push 前などに行うようにしましょう。

plan

terraform plan コマンドを実行すると、現在の設定で更新作業を実行したことで発生するインフラの更新計画が表示されます。

計画は主に、差分の表示と、追加・変更・削除されるリソースの数、という構成で表示されます。
例えば 2 リソースの追加、1 リソースの変更が行われることが予想される際の実行計画は次のようになります。

なお、この実行計画の表示は後続する apply を実行した際にも行われます。
が、apply を行う前には plan を実行して変更内容をあらかじめ把握しておくようにしましょう。

apply

terraform apply コマンドを実行すると、指定の構成情報に従ってリソースの更新作業を実行します。

と言ってもすぐに実行されるわけではなく、apply を実行することで実行計画が表示され、コンソール上で問われる最終確認に対して Yes を入力することで初めて実行されます。

import

terraform import コマンドを実行すると、既に存在しているリソースの情報を terraform にインポートすることができます。terraform で 1 からリソース構成を作成するのではなく、既に存在するリソース構成に合わせて terraform を構築する場合に用いられるコマンドです。

この使用方法については、別途紹介したいと思います。

.tf ファイルの書き方

Provider ブロック

Provider ブロックはその名の通り、管理したいリソースの属するプロバイダーの情報を指定するブロックです。今回は GCP を使用するので、プロジェクト情報やリージョン情報、認証情報などをここで指定します。

GOOGLE_CLOUD_KEYFILE_JSON 変数に認証ファイルの情報を入れておけば、credential は無くてもいけるみたいです。(逆も然り)

provider 毎に設定が異なると思うので、GCP 以外を使用する場合には公式 doc を確認しましょう。

https://www.terraform.io/docs/providers/index.html

terraform ブロック

terraform ブロックでは、使用する terraform の情報を指定します。最低限 terraform のバージョン情報があれば良いのですが、terraform の state 情報を管理する backend の指定もここで行うことができます。今回は管理場所として GCS のバケットを指定しています。

backend を指定する際に注意することは以下の 2 点です。

  1. state 情報を管理するバケットは、既に存在しているバケットを指定しなければならない。
  2. backend を指定したあとは、terraform init を実行しなければいけない。

初期状態で、resource ブロックで作成したバケットを指定してもエラーになります。
そのため、あらかじめ手作業でバケットを作成しておくか、あるいは terraform ブロックで backend を指定しない状態で resource 宣言を実行し、バケットを作成してから backend 宣言を記載する、などの対応が必要になります。

なお、backend を指定しない場合はローカルに state ファイルが保存されます。逆に backend を指定すると、ローカルには state ファイルは保存されないようです。

今回は手元で state ファイルを見守っていたいので、あえて backend は指定しないで進めたいと思います。

locals ブロック

locals ブロックで宣言した変数は、他のブロックから値を参照できるようになります。
例えば以下のように宣言された project と region は

次のように、”local.xxx” の形で参照できます。

気をつけることとしては、ブロックは locals なのに参照するときは local なことくらいですかね。

Resource ブロック

resource ブロックは、各種インフラリソースを定義するブロックです。リソースによって定義する方法が変わってくるので、ここも都度ドキュメントを参照するようにしましょう。

ここでは試しに、GCS と Pub/Sub の設定をしてみましょう。

GCS

簡単な GCS のバケット作成のための定義は以下のようになります。

名前と場所、クラスを指定するだけの簡易構成ですね。もちろんそれ以上の設定を行うこともできます。

GCS に関するドキュメントは次の URL 先にあります。

https://www.terraform.io/docs/providers/google/r/storage_bucket.html

Pub/Sub

今度は pubsub で簡単なトピックとサブスクリプションを定義してみましょう。

今回は雰囲気を見るだけなので、細かい設定値は気にしません。親トピックと、pull 型の子サブスクリプションを設定したという感じです。

上記設定で terraform apply を実行すると、期待通りにリソースが作成されました。

この設定に関しても公式を読みましょう。こんなの何もみないで書けるわけがないんです。

https://www.terraform.io/docs/providers/google/r/pubsub_subscription.html

 

 

次回

今回の記事は既に長くなったのでここで終わろうと思います。

まだまだ出来ていない操作もあるので、それは次回以降の記事で触れていこうと思います。

以上、ここまでご覧いただきありがとうございました。

 

おすすめ書籍

Google Cloud Platform エンタープライズ設計ガイド

Google Cloud Platform 実践Webアプリ開発 ストーリーで学ぶGoogle App Engine

プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで

実践Terraform AWSにおけるシステム設計とベストプラクティス (技術の泉シリーズ(NextPublishing))

GoogleCloudPlatformカテゴリの最新記事