【はじめてのGoogle Cloud】TerraformとgcloudコマンドでDjango AppをGAEにデプロイしてみた

2021.11.22

公式チュートリアルの内容を自分なりにまとめてみました。

正直チュートリアルの内容そのままなので、Terraformを使ったデプロイ以外は目新しい内容は無いです。

前提

こちらを参考に初期設定は済ませておいてください。

特に初めてGoogle Cloudでプロジェクトを作成する方は、課金設定各種APIの有効化App Engineの初期化など色々やことがあります。

サンプルアプリケーションの作成

Google Cloud側でこちらにサンプルアプリケーションを用意してくれています。

Djangoのチュートリアルのその1&その2の内容なので自分で作ってみるのもアリです。

注意点としては、Google Cloud上で動作させるためsettings周りのコードなどを少し修正する必要があります。 こちらに詳細が書いてあるので、目を通しておくと良いと思います。

リソースの作成

当初はTerraformでほとんどのリソース作成しようと考えていたんですが、デプロイのライフサイクルの違いやgcloudコマンドを利用した方が楽なリソースがあったので、最終的には割と簡素になりました。

  • main.tf
provider "google" {
  project = var.project_name
  region  = "asia-northeast1"
  zone    = "asia-northeast1-a"
}

# project
data "google_project" "project" {
}

# database
resource "random_id" "db_name_suffix" {
  byte_length = 4
}

resource "google_sql_database_instance" "postgres" {
  name             = "arai-test-postgres-${random_id.db_name_suffix.hex}"
  project          = data.google_project.project.project_id
  database_version = "POSTGRES_13"
  settings {
    tier = "db-f1-micro"
  }
  deletion_protection = false
}

resource "google_sql_database" "database" {
  name     = "arai-test-db"
  instance = google_sql_database_instance.postgres.name
}

# secret manager
resource "google_secret_manager_secret" "secret" {
  secret_id = "django_settings"
  replication {
    automatic = true
  }
}

# variables
variable "project_name" {
}
  • リソース作成コマンド

terraform apply

手動設定

ここからは手動での設定です。

Terraformでも設定可能な項目もありますが、変更のライフサイクルが異なることからあえて分けています。

データベースユーザーの作成

  • コマンド ※コンソールからでも可
gcloud sql users create <DATABASE_USERNAME> \
    --instance <INSTANCE_NAME> \
    --password <DATABASE_PASSWORD>

データベースの設定

  • .envの生成
echo DATABASE_URL=postgres://,<DATABASE_USERNAME>:<DATABASE_PASSWORD>@//cloudsql/<PROJECT_ID>:<REGION>:<INSTANCE_NAME>/<DATABASE_NAME> > .env
echo SECRET_KEY=$(cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 50 | head -n1) >> .env
  • Cloud SQL Auth プロキシの起動

Cloud SQL Auth プロキシを利用することで、ローカルのアプリケーションからCloud SQLと通信する事が可能です。 こちらを参考にCloud SQL Auth プロキシをダウンロードしておきます。

./cloud_sql_proxy -instances="<PROJECT_ID>:<REGION>:<INSTANCE_NAME>"=tcp:5432
  • DBマイグレーション

Cloud SQLのDBを初期化します。

export GOOGLE_CLOUD_PROJECT=<PROJECT_ID> USE_CLOUD_SQL_AUTH_PROXY=true
python manage.py makemigrations
python manage.py makemigrations polls
python manage.py migrate
python manage.py collectstatic
  • スーパーユーザーの作成

管理画面アクセス用のユーザー作成です。

export GOOGLE_CLOUD_PROJECT=<PROJECT_ID> USE_CLOUD_SQL_AUTH_PROXY=true
python manage.py createsuperuser

Secret Managerの設定

  • コマンド ※コンソールからでも可
gcloud secrets versions add django_settings --data-file .env

アプリのデプロイ

アプリケーションのデプロイは、gcloudコマンドを利用します。

App Engine のデプロイには、構成情報が記載されているapp.yamlが必要です。

app.yamlの詳細はこちらをご覧ください。

  • デプロイコマンド
gcloud app deploy

動作確認

下記のコマンドでデプロイされたウェブアプリケーションのURLが取得できます。

gcloud app browse

下記はAdmin画面になりますが、Google Cloud上でアプリケーションが動作しているのが確認できました。

あと片付け

  • Terraformでのリソースの削除

terraform destroy

  • その他のリソースの削除

今回ですと、App Engineのリソースに関してはTerraformで削除できません。

app.yamlserviceを指定していない場合は、defaultサービスにデプロイした分のバージョンが追加されているはずです。

新規サービスを作ってデプロイしていれば、サービスを削除すれば良いですが、defaultサービスは削除できないため、アプリケーションの設定より「アプリケーションを無効にする」しか方法はなさそうです。

また、プロジェクト自体を削除してもいいという方は、こちらを参考に削除すると良いと思います。

あとがき

今回はチュートリアルを参考に、一部のリソースの作成をTerraformで行ってみたのですが、「Terraformで作成&管理すべきリソース」と「gcloudで作成&管理すべきリソース」の境界点がなんとなく分かってきました。

特にApp EngineはTerraformで管理すべきではないと思いました。

というのも、Terraformを使ってリソース管理することはできるのですが、App Engine自体はdestroyしても消えないので、「apply -> destory -> apply」といったかんじでリソース再作成すると、already exist errorでエラーになります。

Terraformを使って「サービスのバージョンを増やしたり」「トラフィックを移行したり」といったことは可能ですが、gcloudコマンドでも同等のことができます。

一方で、gcloudコマンドを使う場合は、Terraformの他のリソースがApp Engineのidやnameを参照したい場合に少し面倒です。 こういった場合は、通常TerraformのData Sourcesを利用するかと思いますが、ドキュメントを眺める限りそれっぽいのがないので、variablesで設定するしかなさそうです。

なにぶん素人なので、何か間違っていることやいい方法など知っている方がいればコメント頂けると幸いです。