Skip to content

Commit 2f7e395

Browse files
committed
Add Cloud Run service for PYATS
1 parent b35698a commit 2f7e395

10 files changed

Lines changed: 311 additions & 0 deletions

File tree

cloud/plan/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ To provision the cloud infrastructure:
1313
1. Provision the [Terraform backend](tf-backend/README.md)
1414
1. Provision the [Docker repository](docker-repository/README.md)
1515
1. Provision the [storage bucket](storage-bucket/README.md)
16+
1. Provision the [service](service/README.md)

cloud/plan/service/.terraform.lock.hcl

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cloud/plan/service/README.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Service
2+
3+
This root module provisions the resources required for the service.
4+
5+
## Environments
6+
7+
There are multiple environments that replicate the resources which are represented as Terraform workspaces:
8+
9+
* `dev`
10+
* `test`
11+
* `prod`
12+
13+
Set the target environment, for example:
14+
15+
```bash
16+
export ENVIRONMENT=dev
17+
```
18+
19+
## Provisioning
20+
21+
1. Change directory:
22+
23+
```bash
24+
cd cloud/plan/service
25+
```
26+
27+
1. Authenticate with Google Cloud:
28+
29+
```bash
30+
gcloud auth application-default login
31+
```
32+
33+
1. Initialise Terraform:
34+
35+
```bash
36+
terraform init
37+
```
38+
39+
1. Create a Terraform workspace for the environment:
40+
41+
```bash
42+
terraform workspace new ${ENVIRONMENT}
43+
```
44+
45+
1. Apply the changes:
46+
47+
```bash
48+
terraform apply
49+
```
50+
## Configuring GitHub Actions
51+
52+
For the Dev environment only, configure the [CI workflow](../../.github/workflows/ci.yml) with credentials to deploy
53+
images to the service:
54+
55+
1. Obtain the Cloud Run service account private key:
56+
57+
```bash
58+
terraform output -raw github_action_deploy_private_key
59+
```
60+
61+
1. [Set the GitHub Actions environment secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-an-environment) `GCP_CREDENTIALS_DEPLOY` to the private key
62+
63+
64+
## Destroying
65+
66+
1. Change directory:
67+
68+
```bash
69+
cd cloud/plan/service
70+
```
71+
72+
1. Authenticate with Google Cloud:
73+
74+
```bash
75+
gcloud auth application-default login
76+
```
77+
78+
1. Select the Terraform workspace for the environment:
79+
80+
```bash
81+
terraform workspace select ${ENVIRONMENT}
82+
```
83+
84+
1. Disable deletion protection for the service by modifying `cloud/plan/service/application/main.tf`:
85+
86+
```diff
87+
resource "google_cloud_run_v2_service" "plan" {
88+
+ deletion_protection = false
89+
...
90+
}
91+
```
92+
93+
1. Apply the change:
94+
95+
```bash
96+
terraform apply
97+
```
98+
99+
1. Revert the modification:
100+
101+
```bash
102+
git checkout application/main.tf
103+
```
104+
105+
1. Delete the resources:
106+
107+
```bash
108+
terraform destroy
109+
```
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
resource "google_cloud_run_v2_service" "plan" {
2+
name = "plan"
3+
project = var.project
4+
location = var.region
5+
ingress = "INGRESS_TRAFFIC_ALL"
6+
7+
scaling {
8+
min_instance_count = var.keep_idle ? 1 : 0
9+
max_instance_count = 10
10+
}
11+
12+
template {
13+
service_account = google_service_account.cloud_run_plan.email
14+
15+
containers {
16+
image = "${var.docker_repository_url}/plan:latest"
17+
env {
18+
name = "GCS_BUCKET"
19+
value = var.gcs_bucket_name
20+
}
21+
env {
22+
name = "USE_IAP"
23+
value = var.use_iap
24+
}
25+
ports {
26+
container_port = 8080
27+
}
28+
}
29+
}
30+
31+
depends_on = [
32+
google_project_iam_member.cloud_run_artifact_registry_reader
33+
]
34+
}
35+
36+
resource "google_service_account" "cloud_run_plan" {
37+
account_id = "cloud-run-plan"
38+
}
39+
40+
resource "google_cloud_run_v2_service_iam_binding" "plan_run_invoker" {
41+
name = google_cloud_run_v2_service.plan.name
42+
project = var.project
43+
location = var.region
44+
45+
role = "roles/run.invoker"
46+
members = ["allUsers"]
47+
}
48+
49+
data "google_project" "main" {
50+
project_id = var.project
51+
}
52+
53+
resource "google_project_iam_member" "cloud_run_artifact_registry_reader" {
54+
project = var.docker_repository_project
55+
role = "roles/artifactregistry.reader"
56+
member = "serviceAccount:service-${data.google_project.main.number}@serverless-robot-prod.iam.gserviceaccount.com"
57+
}
58+
59+
resource "google_storage_bucket_iam_member" "cloud_run_storage_bucket_reader" {
60+
bucket = var.gcs_bucket_name
61+
role = "roles/storage.objectViewer"
62+
member = "serviceAccount:${google_service_account.cloud_run_plan.email}"
63+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "cloud_run_url" {
2+
description = "Cloud Run URI"
3+
value = google_cloud_run_v2_service.plan.uri
4+
}
5+
6+
output "service_account_id" {
7+
description = "Cloud Run service account ID"
8+
value = google_service_account.cloud_run_plan.id
9+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
variable "project" {
2+
description = "GCP project"
3+
type = string
4+
}
5+
6+
variable "region" {
7+
description = "GCP region"
8+
type = string
9+
}
10+
11+
variable "docker_repository_project" {
12+
description = "Docker repository GCP project"
13+
type = string
14+
}
15+
16+
variable "docker_repository_url" {
17+
description = "Docker repository URL"
18+
type = string
19+
}
20+
21+
variable "keep_idle" {
22+
description = "Whether to keep an instance idle to prevent cold starts"
23+
type = bool
24+
}
25+
26+
variable "gcs_bucket_name" {
27+
description = "GCS bucket name for assets"
28+
type = string
29+
}
30+
31+
variable "use_iap" {
32+
description = "Boolean on whether to use IAP or not"
33+
type = bool
34+
}

cloud/plan/service/main.tf

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
terraform {
2+
backend "gcs" {
3+
bucket = "dft-rlg-schemes-gis-dev-tf-backend"
4+
prefix = "service"
5+
}
6+
}
7+
8+
provider "google" {
9+
project = local.project
10+
}
11+
12+
locals {
13+
env = terraform.workspace
14+
project = "${var.project_prefix}-${local.env}"
15+
config = {
16+
dev = {
17+
use_iap = false
18+
keep_idle = false
19+
}
20+
}
21+
}
22+
23+
24+
data "terraform_remote_state" "docker_repository" {
25+
backend = "gcs"
26+
config = {
27+
bucket = "${var.project_prefix}-dev-tf-backend"
28+
prefix = "docker-repository"
29+
}
30+
}
31+
32+
data "terraform_remote_state" "storage_bucket" {
33+
backend = "gcs"
34+
config = {
35+
bucket = "${var.project_prefix}-dev-tf-backend"
36+
prefix = "storage-bucket"
37+
}
38+
workspace = local.env
39+
}
40+
41+
resource "google_project_service" "run" {
42+
project = local.project
43+
service = "run.googleapis.com"
44+
}
45+
46+
module "application" {
47+
source = "./application"
48+
project = local.project
49+
region = var.location
50+
docker_repository_project = data.terraform_remote_state.docker_repository.outputs.project
51+
docker_repository_url = data.terraform_remote_state.docker_repository.outputs.url
52+
keep_idle = local.config[local.env].keep_idle
53+
gcs_bucket_name = data.terraform_remote_state.storage_bucket.outputs.bucket_name
54+
use_iap = local.config[local.env].use_iap
55+
56+
depends_on = [
57+
google_project_service.run,
58+
]
59+
}

cloud/plan/service/outputs.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "cloud_run_url" {
2+
description = "Cloud run URI"
3+
value = module.application.cloud_run_url
4+
}

cloud/plan/service/variables.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
variable "project_prefix" {
2+
description = "GCP project prefix"
3+
type = string
4+
default = "dft-rlg-schemes-gis"
5+
}
6+
7+
variable "location" {
8+
description = "GCP location"
9+
type = string
10+
default = "europe-west1"
11+
}

cloud/plan/service/versions.tf

Whitespace-only changes.

0 commit comments

Comments
 (0)