Terraformで運用しているLineBot家計簿をGCPで使う
はじめに
私は自分で作ったLineBotを使って家計簿をつけています。
クラウドにはGoogle Cloud Platform(GCP)の無料枠を使っていて、データベースにはCloud SQL(MySQL)を使っています。
自分でデータを集めているので、以前にもApache Supersetなどを用いてデータ分析をしていました。
しかしながら、無料枠を使っていく中で、無料枠が終わって、別の保有しているアカウントに移行したい時に**まったく構成管理が宣言的にできていないことに気づいて、今回はTerraformを使ってやっていこうと思います。
Terraformについて
何をするものなのか
Terraformとはインフラのバージョニング、変更、ビルドを安全に効率的に行うためのツールです
特徴
以下のような特徴があります。
- Instrastructure as Code: 宣言的にインフラを構築することができる
- 実行計画を立てられる: Stateによって変更をインクリメンタルにできる
- リサーチグラフ: 可視化できる
- 複雑な自動化も可能: あらゆる要求に応えることができる
注意点としての特徴もあります。
- Rollbackを自動で行ってくれない
インストール方法
Homebrewを使って簡単にインストールすることができます。
brew install terraform
インストールができたら、正しく実行できるかを確認してください。
terraform -v
Terraformの設定ファイル
指定ファイルは*.tf
のようにtf
拡張子を使って設定を書き込んでいきます。
インフラを構築する
ここから以下のように順番に、概念を解説しながら説明します。
目標とするアーキテクチャ以下の通りです。
また、今回構築していくディレクトリ構造は以下の通りになっています。
- .gcp - .terraform
APIを有効か
Terraformによって操作するにはGCPのAPIを有効化をしなければなりません。
以下の項目を有効化します。
Cloud Resource Manager API
Cloud SQL Admin API
App Engine Admin API
Provider
Providerとはどこのクラウド環境にデプロイをするのかを指定します。
以下のようにgoogle
を指定してGCPへデプロイするようにします。
.terraform/provider.tf
を作成します。
provider "google" { credentials = "${file(".gcp/private_key.json")}" project = "LineBot Terraform" region = "asia-northeast1" }
このようにして指定できます。
credentials
: 認証情報。サービスアカウントがあるディレクトリproject
: GCP上でのプロジェクトの名前region
: どのリージョンかを指定
また、これを使うためにはプラグインをいれないといけません。
terraform init .terraform/
するとplugins
ディレクトリが.terraform/
以下に作られますのでgitignore
に追記した方がいいと思います。
Resource
Resourceとはインスタンス、クラスタなどの構成要素のことです。
1. Project
まずProjectを作成します。
resource "google_project" "my_project" { name = "LineBot Terraform" project_id = "line-terraform-0000" }
2. App Engine
Google App Engineを設定します。
resource "google_app_engine_application" "app" { project = "${google_project.my_project.project_id}" location_id = "us-central' }
ここで${}
によって変数展開をしています。先ほど1.
で"google_project" "my_project"
とを定義したので、そのproject_id
を展開しています。
3. SQL
次にCloud SQLを設定します。
まず最初にインスタンスを作ります。
resource "google_sql_database_instance" "master" { name = "master-database-instance" project = "${google_project.my_project.project_id}" database_version = "MYSQL_5_7" settings { tier = "db-f1-micro" } }
次にデータベースを作成します。
resource "google_sql_database" "database" { name = "yamashita-bank" instance = "${google_sql_database_instance.master.name}" charset = "sjis" collation = "sjis_japanese_ci" }
そして次にユーザーを作ります。
resource "google_sql_database" "users" { name = "root" instance = "${google_sql_database_instance.master.name}" }
4. Cloud Functions
次にCloud Functionsを設定していきます。
resource "google_cloudfunctions_function" "test" { name = "batch-functions" entry_point = "MontlyBatch" project = "${google_project.my_project.project_id}" region = "asia-northeast1" trigger_http = true source_archive_bucket = "${google_storage_bucket.bucket.name}" source_archive_object = "${google_storage_bucket_object.archive.name}" }
5. Google Cloud Storage
以下のようにGoogle Cloud Storageも作っておきます。
これらは、Cloud Functionsのソースが置かれたりします。
resource "google_storage_bucket" "bucket" { name = "cloudfunction-deploy" } data "archive_file" "http_trigger" { type = "zip" output_path = "${path.module}/files/http_trigger.zip" source { content = "${file("${path.module}/files/http_trigger.js")}" filename = "index.js" } } resource "google_storage_bucket" "bucket" { name = "line-bot-bucket" location = "JP" } resource "google_storage_bucket_object" "archive" { name = "file" bucket = "${google_storage_bucket.bucket.name}" }
実行計画
以下のコマンドを叩いて実行計画を立てます。まだ、実際には作られませんので安心してください。
terraform plan .terraform/
主要な部分を取り出します。
Plan: 8 to add, 0 to change, 0 to destroy.
8つか追加されるということです。
実行する
apply
コマンドを使って実行します。
terraform apply .terraform/
すると以下のように確認がでるのでyes
を入力します。
Plan: 8 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes
いくつもできるので、GAEの部分を抜粋します。
google_app_engine_application.app: Creating... auth_domain: "" => "<computed>" code_bucket: "" => "<computed>" default_bucket: "" => "<computed>" default_hostname: "" => "<computed>" feature_settings.#: "" => "<computed>" gcr_domain: "" => "<computed>" location_id: "" => "us-central" name: "" => "<computed>" project: "" => "line-terraform-0000" serving_status: "" => "<computed>" url_dispatch_rule.#: "" => "<computed>"
ここで<computed>
はアプリケーションの生成時に決定されるものです。
状態ファイル(state)を設定する
backend
を指定することによって.tfstate
であるものにできます。
terraform { backend "gcs" { bucket = "tf-state-prod" prefix = "terraform/state" } }
クリーンアップ
以下のコマンドですべて削除できます。
terraform apply .terrform/
おまけ
バリデーションやフォーマットを直すことができます。
terraform validate .terraform
またバリデーションが終わるとフォーマットすることをおすすめします。
terraform fmt
これによって差分が出にくくなります。
まとめ
Terraformによって構築をすることができました。 しかし、アーキテクチャを作っているだけでアプリケーションがデプロイできているわけではありません。
今度はAnsibleを用いて構成管理をやってみようかなと思います。