Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
eliasecchig committed Sep 18, 2024
1 parent 4173e87 commit 5f25b40
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ The application leverages [**Terraform**](http://terraform.io) to define and pro
![Alt text](../images/connection_cb.gif)

3. **Configure Terraform Variables**

- Edit [`deployment/terraform/vars/env.tfvars`](../terraform/vars/env.tfvars) with your Google Cloud settings.

| Variable | Description | Required |
Expand All @@ -67,6 +68,7 @@ The application leverages [**Terraform**](http://terraform.io) to define and pro
Other optional variables include: telemetry and feedback BigQuery dataset IDs, log filters, sink names, service account names, bucket name suffixes, artifact registry repository name, and various role assignments for Cloud Run and CICD.

4. **Deploy Infrastructure with Terraform**

- Open a terminal and navigate to the Terraform directory:

```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ locals {
"bigquery.googleapis.com",
"cloudresourcemanager.googleapis.com",
]

shared_services = [
"aiplatform.googleapis.com",
"run.googleapis.com",
Expand All @@ -18,7 +18,7 @@ locals {
"serviceusage.googleapis.com",
"logging.googleapis.com"
]

projects = {
prod = var.prod_project_id
staging = var.staging_project_id
Expand All @@ -27,15 +27,15 @@ locals {
}

resource "google_project_service" "cicd_services" {
count = length(local.cicd_services)
project = var.cicd_runner_project_id
service = local.cicd_services[count.index]
count = length(local.cicd_services)
project = var.cicd_runner_project_id
service = local.cicd_services[count.index]
disable_on_destroy = false
}

resource "google_project_service" "shared_services" {
for_each = {
for pair in setproduct(keys(local.projects), local.shared_services) :
for pair in setproduct(keys(local.projects), local.shared_services) :
"${pair[0]}_${replace(pair[1], ".", "_")}" => {
project = local.projects[pair[0]]
service = pair[1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ resource "google_artifact_registry_repository" "my-repo" {
repository_id = var.artifact_registry_repo_name
description = "Repo for Generative AI applications"
format = "DOCKER"
project = var.cicd_runner_project_id
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
project = var.cicd_runner_project_id
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# a. Create PR checks trigger
resource "google_cloudbuild_trigger" "pr_checks" {
name = "pr-checks"
project = var.cicd_runner_project_id
location = var.region
description = "Trigger for PR checks"
name = "pr-checks"
project = var.cicd_runner_project_id
location = var.region
description = "Trigger for PR checks"
service_account = resource.google_service_account.cicd_runner_sa.id

repository_event_config {
repository = "projects/${var.cicd_runner_project_id}/locations/${var.region}/connections/${var.host_connection_name}/repositories/${var.repository_name}"
repository = "projects/${var.cicd_runner_project_id}/locations/${var.region}/connections/${var.host_connection_name}/repositories/${var.repository_name}"
pull_request {
branch = "main"
}
Expand All @@ -21,20 +21,20 @@ resource "google_cloudbuild_trigger" "pr_checks" {
"poetry.lock"
]

include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
}

# b. Create CD pipeline trigger
resource "google_cloudbuild_trigger" "cd_pipeline" {
name = "cd-pipeline"
project = var.cicd_runner_project_id
location = var.region
name = "cd-pipeline"
project = var.cicd_runner_project_id
location = var.region
service_account = resource.google_service_account.cicd_runner_sa.id
description = "Trigger for CD pipeline"
description = "Trigger for CD pipeline"

repository_event_config {
repository = "projects/${var.cicd_runner_project_id}/locations/${var.region}/connections/${var.host_connection_name}/repositories/${var.repository_name}"
repository = "projects/${var.cicd_runner_project_id}/locations/${var.region}/connections/${var.host_connection_name}/repositories/${var.repository_name}"
push {
branch = "main"
}
Expand All @@ -48,33 +48,33 @@ resource "google_cloudbuild_trigger" "cd_pipeline" {
"poetry.lock"
]
substitutions = {
_STAGING_PROJECT_ID = var.staging_project_id
_PROD_PROJECT_ID = var.prod_project_id
_STAGING_PROJECT_ID = var.staging_project_id
_PROD_PROJECT_ID = var.prod_project_id
_BUCKET_NAME_LOAD_TEST_RESULTS = resource.google_storage_bucket.bucket_load_test_results.name
_ARTIFACT_REGISTRY_REPO_NAME = var.artifact_registry_repo_name
_CLOUD_RUN_APP_SA_NAME = var.cloud_run_app_sa_name
_ARTIFACT_REGISTRY_REPO_NAME = var.artifact_registry_repo_name
_CLOUD_RUN_APP_SA_NAME = var.cloud_run_app_sa_name
}

include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]

}

# c. Create Deploy to production trigger
resource "google_cloudbuild_trigger" "deploy_to_prod_pipeline" {
name = "deploy-to-prod-pipeline"
project = var.cicd_runner_project_id
location = var.region
description = "Trigger for deployment to production"
name = "deploy-to-prod-pipeline"
project = var.cicd_runner_project_id
location = var.region
description = "Trigger for deployment to production"
service_account = resource.google_service_account.cicd_runner_sa.id
repository_event_config {
repository = "projects/${var.cicd_runner_project_id}/locations/${var.region}/connections/${var.host_connection_name}/repositories/${var.repository_name}"
repository = "projects/${var.cicd_runner_project_id}/locations/${var.region}/connections/${var.host_connection_name}/repositories/${var.repository_name}"
}
filename = "deployment/cd/deploy-to-prod.yaml"
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
filename = "deployment/cd/deploy-to-prod.yaml"
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
approval_config {
approval_required = true
}
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
locals {
project_ids = {
dev = var.dev_project_id
dev = var.dev_project_id
}
}

# 4. Grant Cloud Run SA the required permissions to run the application
resource "google_project_iam_member" "cloud_run_app_sa_roles" {
for_each = {
for pair in setproduct(keys(local.project_ids), var.cloud_run_app_roles) :
for pair in setproduct(keys(local.project_ids), var.cloud_run_app_roles) :
join(",", pair) => {
project = local.project_ids[pair[0]]
role = pair[1]
Expand All @@ -17,4 +17,4 @@ resource "google_project_iam_member" "cloud_run_app_sa_roles" {
project = each.value.project
role = each.value.role
member = "serviceAccount:${google_service_account.cloud_run_app_sa.email}"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,38 @@ module "log_export_to_bigquery" {
source = "terraform-google-modules/log-export/google"
version = "8.1.0"

log_sink_name = var.telemetry_sink_name
parent_resource_type = "project"
parent_resource_id = var.dev_project_id
destination_uri = "bigquery.googleapis.com/projects/${var.dev_project_id}/datasets/${var.telemetry_bigquery_dataset_id}"
filter = var.telemetry_logs_filter
bigquery_options = { use_partitioned_tables = true }
log_sink_name = var.telemetry_sink_name
parent_resource_type = "project"
parent_resource_id = var.dev_project_id
destination_uri = "bigquery.googleapis.com/projects/${var.dev_project_id}/datasets/${var.telemetry_bigquery_dataset_id}"
filter = var.telemetry_logs_filter
bigquery_options = { use_partitioned_tables = true }
unique_writer_identity = true

}

resource "google_bigquery_dataset" "feedback_dataset" {
project = var.dev_project_id
project = var.dev_project_id
dataset_id = var.feedback_bigquery_dataset_id
friendly_name = var.feedback_bigquery_dataset_id
location = var.region

}

module "feedback_export_to_bigquery" {
source = "terraform-google-modules/log-export/google"
version = "8.1.0"
log_sink_name = var.feedback_sink_name
parent_resource_type = "project"
parent_resource_id = var.dev_project_id
destination_uri = "bigquery.googleapis.com/projects/${var.dev_project_id}/datasets/${var.feedback_bigquery_dataset_id}"
filter = var.feedback_logs_filter
bigquery_options = { use_partitioned_tables = true }
source = "terraform-google-modules/log-export/google"
version = "8.1.0"
log_sink_name = var.feedback_sink_name
parent_resource_type = "project"
parent_resource_id = var.dev_project_id
destination_uri = "bigquery.googleapis.com/projects/${var.dev_project_id}/datasets/${var.feedback_bigquery_dataset_id}"
filter = var.feedback_logs_filter
bigquery_options = { use_partitioned_tables = true }
unique_writer_identity = true
}

resource "google_bigquery_dataset" "telemetry_logs_dataset" {
project = var.dev_project_id
project = var.dev_project_id
dataset_id = var.telemetry_bigquery_dataset_id
friendly_name = var.telemetry_bigquery_dataset_id
location = var.region
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.3.0"
}
}
}

resource "google_storage_bucket" "logs_data_bucket" {
name = "${var.dev_project_id}-logs-data"
location = var.region
Expand All @@ -13,6 +22,7 @@ resource "google_storage_bucket" "logs_data_bucket" {
count = length(data.google_storage_bucket.existing_bucket) > 0 ? 0 : 1
}


data "google_storage_bucket" "existing_bucket" {
name = "${var.dev_project_id}-logs-data"
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ variable "cloud_run_app_sa_name" {
variable "cloud_run_app_roles" {
description = "List of roles to assign to the Cloud Run app service account"
type = list(string)
default = [
default = [
"roles/aiplatform.user",
"roles/discoveryengine.editor",
"roles/logging.logWriter",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,61 @@ locals {

# Data source to get project numbers
data "google_project" "projects" {
for_each = local.project_ids
for_each = local.project_ids
project_id = each.value
}

# 1. Assign roles for the CICD project
resource "google_project_iam_member" "cicd_project_roles" {
for_each = toset(var.cicd_roles)

project = var.cicd_runner_project_id
role = each.value
member = "serviceAccount:${resource.google_service_account.cicd_runner_sa.email}"
project = var.cicd_runner_project_id
role = each.value
member = "serviceAccount:${resource.google_service_account.cicd_runner_sa.email}"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]

}

# 2. Assign roles for the other two projects (prod and staging)
resource "google_project_iam_member" "other_projects_roles" {
for_each = {
for pair in setproduct(keys(local.project_ids), var.cicd_sa_deployment_required_roles) :
for pair in setproduct(keys(local.project_ids), var.cicd_sa_deployment_required_roles) :
"${pair[0]}-${pair[1]}" => {
project_id = local.project_ids[pair[0]]
role = pair[1]
}
}

project = each.value.project_id
role = each.value.role
member = "serviceAccount:${resource.google_service_account.cicd_runner_sa.email}"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
project = each.value.project_id
role = each.value.role
member = "serviceAccount:${resource.google_service_account.cicd_runner_sa.email}"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
}

# 3. Allow Cloud Run service SA to pull containers stored in the CICD project
resource "google_project_iam_member" "cicd_run_invoker_artifact_registry_reader" {
for_each = local.project_ids
project = var.cicd_runner_project_id
project = var.cicd_runner_project_id

role = "roles/artifactregistry.reader"
member = "serviceAccount:service-${data.google_project.projects[each.key].number}@serverless-robot-prod.iam.gserviceaccount.com"
role = "roles/artifactregistry.reader"
member = "serviceAccount:service-${data.google_project.projects[each.key].number}@serverless-robot-prod.iam.gserviceaccount.com"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]

}

# 4. Grant Cloud Run SA the required permissions to run the application
resource "google_project_iam_member" "cloud_run_app_sa_roles" {
for_each = {
for pair in setproduct(keys(local.project_ids), var.cloud_run_app_roles) :
for pair in setproduct(keys(local.project_ids), var.cloud_run_app_roles) :
join(",", pair) => {
project = local.project_ids[pair[0]]
role = pair[1]
}
}

project = each.value.project
role = each.value.role
member = "serviceAccount:${google_service_account.cloud_run_app_sa[split(",", each.key)[0]].email}"
project = each.value.project
role = each.value.role
member = "serviceAccount:${google_service_account.cloud_run_app_sa[split(",", each.key)[0]].email}"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
}

Expand All @@ -70,12 +70,12 @@ resource "google_service_account_iam_member" "cicd_run_invoker_token_creator" {
service_account_id = google_service_account.cicd_runner_sa.name
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:${resource.google_service_account.cicd_runner_sa.email}"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
}
# Special assignment: Allow the CICD SA to impersonate himself for trigger creation
resource "google_service_account_iam_member" "cicd_run_invoker_account_user" {
service_account_id = google_service_account.cicd_runner_sa.name
role = "roles/iam.serviceAccountUser"
member = "serviceAccount:${resource.google_service_account.cicd_runner_sa.email}"
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
}
depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.shared_services]
}
Loading

0 comments on commit 5f25b40

Please sign in to comment.