LoginSignup
0
0

はじめに

「やっぱり作ったアプリはデプロイしたい…!」「格好良くIaCも触りたい…!」という独学未経験の初心者の奮闘記録です。

もし間違い等ありましたらご指摘頂けると嬉しいです。

Terraformって何なの?

インフラ構成をコードで管理できるIaC(Infrastructure as Code)ツールの1つ。

クラウドインフラの構成は、コンソール画面やSDKを用いて行えますが、どういった構成にしているかが見えず共有しにくくなります。また、以前の構成に戻したくなっても操作が面倒です。

それに対してIaCでは、コードで構成を管理できるので、インフラを可視化、共有がしやすく、変更履歴も残せます。

細かい部分については、以下の記事をとてもわかりやすいのでご覧ください。

Terraformの手順

Terraformのバージョン管理を簡単に切り替えながら取り扱えるので、tfenvをインストールします。

$ brew install tfenv  # tfenvのインストール

$ tfenv install x.x.x<使用したいバージョン>  # 使用したいTerraformのバージョンをインストール

$ tfenv use x.x.x<使用したいバージョン>  # 使用したいTerraformのバージョンを選択

素のTerraformをインストールしても良いです。そして以下の順序でインフラ構成を適用します。

 

  1. プロジェクトのルートディレクトリにて、Terraform用ディレクトリを作成します。
  2. 作成したディレクトリに移動し、main.tfを作成、インフラ構成を書く。以降、ディレクトリ移動せず実施する。
  3. terraform initを実行、初期化する。
  4. terraform planを実行、作成されるインフラ構成の確認をする。
  5. terraform applyを実行、④で確認した内容でインフラを構成する。エラーがあれば吐かれる。
     

私はよく確認しておらず、ディレクトリに移動しinitすることを知りませんでした。変なところでハマってしまい時間を費やしてまった…。

Terraformの構成

今回、デプロイ先はCloud Runで、さらにnginxを使いたかったのでコンテナを2つ立ち上げる必要がありました。「どうしたらええんや…」の頭を抱えていたところ、以下の記事を見つけましたので参考にさせて頂きました。

Cloud Runの認証設定

TerraformがCloud Runにアクセス出来るよう、まず認証設定をします。
以下2点を済ませておきましょう。

  1. gcloud CLIをインストール
  2. GCPにてプロジェクトを作成

作成したプロジェクトIDを用いて、gcloudでの操作対象としてアクティブにします。

$ gcloud config set project <プロジェクトID>

サービスアカウントを作成します。

gcloud iam service-accounts create サービスアカウントの名前 \
		--description="説明文(任意)" \
		--display-name="表示名"

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

gcloud projects add-iam-policy-binding <プロジェクトID> \
		--member="serviceAccount:<作成したサービスアカウント名>@<プロジェクトID>.iam.gserviceaccount.com" \
		--role="roles/editor"

サービスアカウントキーをローカルに取得します。

gcloud iam service-accounts keys create <任意のパス>/key.json \
		--iam-account <作成したサービスアカウント名>@<プロジェクトID>.iam.gserviceaccount.com

サービスアカウントキーを用いた認証は公式で推奨されてませんが、手早くデプロイするため採用しました。
キーの管理のベストプラクティスが紹介されていますので、参考にし管理には十分注意しましょう。
公式の認証方法の選択フローもあるので、キーを使いたくない場合はこちらも参考にしてください。

Artifact Registryの設定

main.tf
provider "google" {
    project = var.project_id
    region  = var.default_region
    credentials = file("path/to/key.json")  # サービスアカウントキーのパス
}


provider "google-beta" {
    project = var.project_id
    region  = var.default_region
}


resource "google_artifact_registry_repository" "your_project_image_repository" {
    provider      = google-beta
    location      = var.default_region
    repository_id = var.repository_id
    description   = "your-project"
    format        = "DOCKER"

    cleanup_policy_dry_run = false
    cleanup_policies {
        id     = "keep_minimum-versions"
        action = "KEEP"
        most_recent_versions {
        keep_count = 3
        }
    }
}
variable.tf
variable "default_region" {
    description = "default region"
    type        = string
    default     = "asia-northeast1"
}

variable "project_id" {
    description = "project id"
    type        = string
    default     = "your-api-project"
}

variable "repository_id" {
    description = "repository id"
    type        = string
    default     = "your-project-image-repository"
}

まずは、コンテナを立ち上げるためのdockerイメージのリポジトリを作ります。
上記の内容でterraform init ▷ terraform plan ▷ terraform applyを実行することで、Artifact Registryが作成されます。

Artifact Registryにdockerイメージをプッシュする

デプロイ先でコンテナを立ち上げるためのdockerイメージを、Dockerfileがあるディレクトリでビルドし、プッシュします。

ちなみにnginx側とアプリ側のDockerfileは以下のようになっています。

nginx側のDockerfile
FROM nginx:1.17.4-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY default.conf /etc/nginx/conf.d
アプリ側のDockerfile
FROM python:3.11

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR /code

COPY requirements.txt ./
RUN python3 -m pip install --upgrade pip setuptools
RUN pip install -r requirements.txt

COPY . ./

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 config.wsgi:application

ビルドの際、公式の通り、リージョン(asia-northeast1)やホスト名(docker.pkg.dev)、プロジェクトIDなどを含めてタグ付けします。

イメージにレジストリ名をタグ付けする

Docker イメージにレポジトリ名をタグ付けすると、イメージを特定の場所に push するように docker push コマンドが構成されます。

docker build --platform linux/amd64 \
             -f Dockerfile \
             -t asia-northeast1-docker.pkg.dev/your-api-project/your-project-image-repository/your-web-back-image:v1 .

docker push asia-northeast1-docker.pkg.dev/your-api-project/your-project-image-repository/your-web-back-image:v1
docker build --platform linux/amd64 \
             -f Dockerfile \
             -t asia-northeast1-docker.pkg.dev/your-api-project/your-project-image-repository/your-nginx-image:v1 .

docker push asia-northeast1-docker.pkg.dev/your-api-project/your-project-image-repository/your-nginx-image:v1

ビルドする際、--platformでOSとアーキテクチャをlinux/amd64に指定しましょう。私はここで、エラーにハマりました…。

Cloud Runの設定

Cloud Runの構成のため、main.tfに以下を追記します。

main.tf
resource "google_cloud_run_v2_service" "your-project-name" {
    provider = google-beta
    name     = "your-project-name"
    location = var.default_region
    ingress  = "INGRESS_TRAFFIC_ALL"

    template {
        containers {
            name  = "your-web-back-container"
            image = "asia-northeast1-docker.pkg.dev/${var.project_id}/${var.repository_id}/your-web-back-image:v1"
            env {
                name = "PORT"
                value = "8000"
            }
            startup_probe {
                failure_threshold     = 1
                initial_delay_seconds = 0
                timeout_seconds       = 240
                period_seconds        = 240
                tcp_socket {
                    port = 8000
                }
            }
        }

        containers {
            name = "your-nginx-container"
            image = "asia-northeast1-docker.pkg.dev/${var.project_id}/${var.repository_id}/your-nginx-image:v1"
            ports {
                container_port = 8080
            }
            depends_on = [ "your-web-back-container" ]
            startup_probe {
                failure_threshold     = 1
                initial_delay_seconds = 0
                timeout_seconds       = 240
                period_seconds        = 240
                tcp_socket {
                    port = 8080
                }
            }
        }

        scaling {
            min_instance_count = 0
            max_instance_count = 1
        }
    }

    traffic {
        type    = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
        percent = 100
    }
}

再度、terraform init ▷ terraform plan ▷ terraform applyを実行して、無事にCloud Runにデプロイ出来ました!

おわりに

アプリを公開するって本当に大変ですね…。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0