From 27c1c461e8863adaef75edab15b7fa8498aaa02c Mon Sep 17 00:00:00 2001 From: "ry.yamafuji" Date: Fri, 5 Dec 2025 02:16:37 +0900 Subject: [PATCH 1/3] =?UTF-8?q?terraform=E3=81=AE=E5=BF=85=E8=A6=81?= =?UTF-8?q?=E3=81=AA=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme/deploy.md | 11 +++++++++ terraform/af.tf | 5 ++++ terraform/platform.tf | 10 ++++++++ terraform/provider.tf | 5 ++++ terraform/run_job.tf | 30 +++++++++++++++++++++++ terraform/sa.tf | 14 +++++++++++ terraform/sample.tfvars | 10 ++++++++ terraform/variables.tf | 53 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 138 insertions(+) create mode 100644 readme/deploy.md create mode 100644 terraform/af.tf create mode 100644 terraform/platform.tf create mode 100644 terraform/provider.tf create mode 100644 terraform/run_job.tf create mode 100644 terraform/sa.tf create mode 100644 terraform/sample.tfvars create mode 100644 terraform/variables.tf diff --git a/readme/deploy.md b/readme/deploy.md new file mode 100644 index 0000000..0fc0931 --- /dev/null +++ b/readme/deploy.md @@ -0,0 +1,11 @@ +# デプロイの方法について + +## 環境について + +* terraform +* google cloud + * Cloud Run Job + + + + diff --git a/terraform/af.tf b/terraform/af.tf new file mode 100644 index 0000000..fd4fcf8 --- /dev/null +++ b/terraform/af.tf @@ -0,0 +1,5 @@ +resource "google_artifact_registry_repository" "repo" { + location = var.region + repository_id = "cicd-repo-${var.env_name}" + format = "DOCKER" +} \ No newline at end of file diff --git a/terraform/platform.tf b/terraform/platform.tf new file mode 100644 index 0000000..17fcd21 --- /dev/null +++ b/terraform/platform.tf @@ -0,0 +1,10 @@ +# Google CloudのAPIを有効化 + +resource "google_project_service" "services" { + for_each = toset([ + "run.googleapis.com", + "artifactregistry.googleapis.com", + "cloudbuild.googleapis.com", + ]) + service = each.key +} \ No newline at end of file diff --git a/terraform/provider.tf b/terraform/provider.tf new file mode 100644 index 0000000..fdeb7be --- /dev/null +++ b/terraform/provider.tf @@ -0,0 +1,5 @@ +# Google Providerの設定 +provider "google" { + project = var.project_id + region = var.region +} \ No newline at end of file diff --git a/terraform/run_job.tf b/terraform/run_job.tf new file mode 100644 index 0000000..9d5b1d1 --- /dev/null +++ b/terraform/run_job.tf @@ -0,0 +1,30 @@ +# Cloud Run Jobのリソース +resource "google_cloud_run_job" "job" { + name = "${var.job_name}-${var.env_name}-job" + location = var.region + + # サービスアカウントを指定 + service_account = google_service_account.job_sa.email + + template { + template { + containers { + image = var.container_image + + resources { + limits = { + cpu = var.cpu_limit + memory = var.memory_limit + } + } + + # env { + # 必要に応じ環境変数を設定 + # name = "ENV_VAR_NAME" + # } + } + timeout_seconds = var.timeout_seconds + } + } +} + diff --git a/terraform/sa.tf b/terraform/sa.tf new file mode 100644 index 0000000..798cc12 --- /dev/null +++ b/terraform/sa.tf @@ -0,0 +1,14 @@ +resource "google_service_account" "job_sa" { + account_id = "sa-${var.job_name}-${var.env_name}" + display_name = "Cloud Run Job Service Account for ${var.job_name} in ${var.env_name} environment" + description = "Cloud Run Job Service Account for ${var.job_name} in ${var.env_name} environment" + project = var.project_id +} + +# IAM role assignment +# Cloud Run Job実行に必要な権限を付与 +resource "google_project_iam_member" "run_job_invoker" { + project = var.project_id + role = "roles/run.invoker" + member = "serviceAccount:${google_service_account.job_sa.email}" +} \ No newline at end of file diff --git a/terraform/sample.tfvars b/terraform/sample.tfvars new file mode 100644 index 0000000..dd838f6 --- /dev/null +++ b/terraform/sample.tfvars @@ -0,0 +1,10 @@ +project_id = "プロジェクトIDを指定してください" +region = "asia-northeast1" +env_name = "dev" + +job_name = "ジョブ名を指定してください" +# コンテナイメージ(CI/CDから渡される想定) + +cpu_limit = "1" +memory_limit = "512Mi" +timeout_seconds = 900 diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..26937d7 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,53 @@ +# GCPプロジェクトIDとリージョン、環境名、ジョブ名の変数定義 +variable "project_id" { + description = "The ID of the GCP project to deploy resources into." + type = string +} +variable "region" { + description = "The GCP region to deploy resources into." + type = string + default = "asia-northeast1" # 東京 +} + +variable "env_name" { + description = "The environment name for the deployment." + type = string + default = "dev" + validation { + condition = contains(["dev", "staging", "prd"], var.env_name) + error_message = "env_name must be one of: dev, staging, prd." + } +} + +variable "job_name" { + description = "The name of the Cloud Run Job." + type = string + default = "get-news-ai" +} + + +# コンテナイメージの変数定義(CI/CDから渡される想定) +variable "container_image" { + description = "The container image for the Cloud Run Job." + type = string +} + + +# Cloud Run Jobの設定変数 +variable "cpu_limit" { + description = "The CPU limit for the Cloud Run Job container." + type = string + default = "1" +} + +variable "memory_limit" { + description = "The memory limit for the Cloud Run Job container." + type = string + default = "512Mi" +} + +variable "timeout_seconds" { + description = "The timeout for the Cloud Run Job." + type = number + default = 300 +} \ No newline at end of file From 6cb9f550f70a2df543754eb4476f82bb2bf087ec Mon Sep 17 00:00:00 2001 From: "ry.yamafuji" Date: Fri, 5 Dec 2025 10:49:58 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E5=88=9D=E5=9B=9ECloudRunJob=E8=B5=B7?= =?UTF-8?q?=E5=8B=95=E7=A2=BA=E8=AA=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 19 +++++++++ readme/components_design/AGENT.md | 61 +++++++++++++++++++++++++++++ readme/deploy.md | 65 +++++++++++++++++++++++++++++++ terraform/run_job.tf | 21 +++++----- terraform/sample.tfvars | 2 +- terraform/variables.tf | 13 ++++--- 6 files changed, 163 insertions(+), 18 deletions(-) create mode 100644 Dockerfile create mode 100644 readme/components_design/AGENT.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..91fd4eb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM python:3.12-slim + +# 必要なパッケージをインストール +RUN apt-get update && apt-get install -y \ + curl + +# pythonパッケージのインストール +COPY requirements.txt . +RUN pip install --upgrade pip +RUN pip install --no-cache-dir -r requirements.txt + +# 作業ディレクトリを設定 +WORKDIR /app + +# アプリケーションコードをコピー +COPY ./src /app + +# コンテナ起動時に実行されるコマンドを指定 +CMD ["python", "main.py"] \ No newline at end of file diff --git a/readme/components_design/AGENT.md b/readme/components_design/AGENT.md new file mode 100644 index 0000000..fe51108 --- /dev/null +++ b/readme/components_design/AGENT.md @@ -0,0 +1,61 @@ + +# エージェントへの目的 + +`terraform`フォルダを確認して`readme/components_design`フォルダに +.drawioファイル(XML形式)で作成してください + +## 役割 + +あなたはシステム構成を考える専門家です。 + +## 規約 + +【要件】 + +* 出力ファイルは`system_components.drawio`としてください。 +* リクエストに指定がない場合は環境変数は`_dev.tfvars`を優先してください。 +* サービスアカウントやロールなどは記載しなくて良い。 +* **重要**terraformに存在しないコンポーネントは使用しないこと +* ユーザーが利用するコンポーネント図と、開発者が利用するコンポーネント図は分離してください + + +【レイアウト要件】 +- Region、VPCを大きな枠で表現 + - Region: 最も外側の枠として配置 + - VPC: Regionの内側に配置 +- 接続線が重ならないよう、コンポーネントを階段状に配置 +- 各コンポーネント間の間隔を100px以上確保 +- ユーザーはVPCの外側に配置(インターネット経由でアクセスする想定) +- コンポーネントは左から右に向かってデータフローを表現(User → Frontend → Backend → Database) + +【スタイル要件】 + +**枠のスタイル:** +- VPC: `fillColor=#D5E8D4;strokeColor=#82b366;dashed=1;verticalAlign=top;fontStyle=1;fontSize=14` +- Region: `fillColor=#E1F5FE;strokeColor=#01579B;dashed=1;verticalAlign=top;fontStyle=1;fontSize=14` +- 枠のラベルは左上に配置(`align=left;spacingLeft=10;spacingTop=5`) + +**接続線:** +- 双方向通信: `endArrow=classic;startArrow=classic;strokeWidth=2` +- 単方向通信: `endArrow=classic;strokeWidth=2` +- HTTPSアクセス: `strokeColor=#4285F4`(青) +- データベース接続: `strokeColor=#DB4437`(赤) +- ストレージアクセス: `strokeColor=#34A853`(緑) +- 接続線にラベルを付ける(例: "HTTPS", "API", "SQL") + +【座標とサイズの目安】 +- Region枠: 幅800-1000px、高さ500-700px +- VPC枠: Region内部で余白50px程度、幅700-900px、高さ400-600px +- コンポーネントアイコン: 78x78 または 80x80 +- コンポーネント間の横間隔: 150-200px +- コンポーネント間の縦間隔: 100-150px + + +**アイコン:** + +- ユーザー/クライアントアイコン + - `shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.user`(共通で使用可能) + +- コンポーネントのアイコンについて以下のマップを参考にしてください + - 以下のアイコンを使用する場合、必ず対応する mxCell テンプレートを使用すること。 + - id / x / y / width / height / parent などは適宜書き換えて構いません。 diff --git a/readme/deploy.md b/readme/deploy.md index 0fc0931..fea0c58 100644 --- a/readme/deploy.md +++ b/readme/deploy.md @@ -1,11 +1,76 @@ # デプロイの方法について +## インストール方法 + +MACの場合 + +```sh +brew tap hashicorp/tap +brew install hashicorp/tap/terraform +# 確認 +terraform -version +``` + + ## 環境について * terraform * google cloud * Cloud Run Job +## 実行する方法 + +```sh +# 初期化を実行する +cd terraform +# Terraformの初期化 +terraform init +# アーティファクトやバケットについては先に生成する +terraform apply \ +-var-file=_dev.tfvars \ +-auto-approve \ +-target="google_artifact_registry_repository.repo" +# DockerファイルをビルドしてGARにプッシュする場合 +cd ../ +# 1. Artifact Registryへの認証設定(初回のみ実行) +source deploy.env +gcloud auth configure-docker "${AR_REGION}-docker.pkg.dev" +# arm64 +source deploy.env +gcloud builds submit --tag "${IMAGE_URI}" . +echo "${IMAGE_URI}" + +# デプロイするコンポーネントを確認する +cd terraform +terraform plan \ +-var-file=_dev.tfvars \ +-var="hash_suffix=${HASH_SUFFIX}" + +# デプロイを実行する +terraform apply \ +-var-file=_dev.tfvars \ +-var="hash_suffix=${HASH_SUFFIX}" \ +-auto-approve +``` +ローカルでビルドで試す場合 +```sh +# デフォルトでビルドする場合 +docker build -t cloud-run-job-base . +# arm64でビルドしたい場合 +docker buildx build -platform linux/amd64,linux/arm64 -t cloud-run-job-base . +# Dockerを実行する(1回だけ実行してコンテナインスタンスを削除する場合) +docker run --rm cloud-run-job-base:latest +``` + +### CI/CDでデプロイを実行する場合 + +**Github(Gitea) Acrtionsで実行する場合** + + +**Cloud Buildで実行する場合** + + +### Big Quderyにデータが取得できた場合をトリガーにしてJOBを実行する方法 diff --git a/terraform/run_job.tf b/terraform/run_job.tf index 9d5b1d1..c6be644 100644 --- a/terraform/run_job.tf +++ b/terraform/run_job.tf @@ -1,30 +1,29 @@ # Cloud Run Jobのリソース -resource "google_cloud_run_job" "job" { +# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_job +resource "google_cloud_run_v2_job" "job" { name = "${var.job_name}-${var.env_name}-job" location = var.region - # サービスアカウントを指定 - service_account = google_service_account.job_sa.email template { template { - containers { - image = var.container_image + # サービスアカウントを指定 + service_account = google_service_account.job_sa.email + containers { + image = "${var.region}-docker.pkg.dev/${var.project_id}/cicd-repo-${var.env_name}/run-job-${var.job_name}-image:${var.hash_suffix}" resources { limits = { cpu = var.cpu_limit memory = var.memory_limit } } - - # env { - # 必要に応じ環境変数を設定 - # name = "ENV_VAR_NAME" - # } } - timeout_seconds = var.timeout_seconds + + timeout = var.timeout + } } + } diff --git a/terraform/sample.tfvars b/terraform/sample.tfvars index dd838f6..b094684 100644 --- a/terraform/sample.tfvars +++ b/terraform/sample.tfvars @@ -7,4 +7,4 @@ job_name = "ジョブ名を指定してください" cpu_limit = "1" memory_limit = "512Mi" -timeout_seconds = 900 +timeout = "1800s" diff --git a/terraform/variables.tf b/terraform/variables.tf index 26937d7..c298ec6 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -26,10 +26,11 @@ variable "job_name" { } -# コンテナイメージの変数定義(CI/CDから渡される想定) -variable "container_image" { +# コンテナイメージのハッシュ値変数定義(CI/CDから渡される想定) +variable "hash_suffix" { description = "The container image for the Cloud Run Job." type = string + default = null } @@ -46,8 +47,8 @@ variable "memory_limit" { default = "512Mi" } -variable "timeout_seconds" { - description = "The timeout for the Cloud Run Job." - type = number - default = 300 +variable "timeout" { + description = "The task timeout in seconds for the Cloud Run Job." + type = string + default = "1800s" } \ No newline at end of file From 6d141ca131d2a2194ef43a87398c5af827fad8d5 Mon Sep 17 00:00:00 2001 From: "ry.yamafuji" Date: Fri, 5 Dec 2025 20:40:52 +0900 Subject: [PATCH 3/3] =?UTF-8?q?CD=E3=82=BD=E3=83=BC=E3=82=B9=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0(gcp=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy_to_gcp.yml | 38 +++++++++++++++++++++++++++++ .gitignore | 7 ++++++ scripts/deploy/init_terraform.sh | 19 +++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 .github/workflows/deploy_to_gcp.yml create mode 100644 scripts/deploy/init_terraform.sh diff --git a/.github/workflows/deploy_to_gcp.yml b/.github/workflows/deploy_to_gcp.yml new file mode 100644 index 0000000..051d0dd --- /dev/null +++ b/.github/workflows/deploy_to_gcp.yml @@ -0,0 +1,38 @@ +name: Gitea Deploy to GCP + +on: + workflow_dispatch: + + pull_request: + branches: + - deploy-prd + - deploy-dev + paths: + - 'src/**' + - 'terraform/**' + +jobs: + deploy: + name: Deploy to GCP + runs-on: gcloud-tf + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Check Deploy Tools + run: | + gcloud --version + terraform --version + + + # - name: Set up Cloud SDK + # uses: google-github-actions/setup-gcloud@v1 + # with: + # project_id: ${{ secrets.GCP_PROJECT_ID }} + # service_account_key: ${{ secrets.GCP_SA_KEY }} + # export_default_credentials: true + + # - name: Run deployment script + # run: | + # chmod +x ./deploy.sh + # ./deploy.sh diff --git a/.gitignore b/.gitignore index 00b439c..2015f53 100644 --- a/.gitignore +++ b/.gitignore @@ -172,3 +172,10 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +# terraform.tfstate files +_*.tfvars +.terraform/ +.terraform.lock.hcl +*.tfstate +*.tfstate.backup +*deploy.env \ No newline at end of file diff --git a/scripts/deploy/init_terraform.sh b/scripts/deploy/init_terraform.sh new file mode 100644 index 0000000..7e57d64 --- /dev/null +++ b/scripts/deploy/init_terraform.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Safe mode(when error,kill script) +set -euo pipefail + +TF_DIR=${TF_DIR:-terraform} + +# GCS S3などで保存する +TF_STATE_BUCKET=${TF_STATE_BUCKET:-cicd-tfstate-bucket} +ENV=${ENV:-dev} +REPO_NAME=${REPO_NAME:-unknown} + +cd "$TF_DIR" + +# --- terraform init 実行 --- +terraform init \ + -backend-config="bucket=${TF_STATE_BUCKET}" \ + -backend-config="prefix=${REPO_NAME}/${ENV}" \ + \ No newline at end of file