Skip to content

Commit

Permalink
OPS: Add terraform config
Browse files Browse the repository at this point in the history
  • Loading branch information
cortadocodes committed Dec 1, 2023
1 parent 7faa0c4 commit 96dbf43
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,6 @@ ENV/
*.sum
.DS_Store
.octue

gcp-credentials.json
.terraform*
2 changes: 2 additions & 0 deletions terraform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gcp-credentials.json
.terraform*
6 changes: 6 additions & 0 deletions terraform/artifact_registry.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "google_artifact_registry_repository" "artifact_registry_repository" {
location = var.region
repository_id = "${var.service_namespace}"
description = "Docker image repository"
format = "DOCKER"
}
143 changes: 143 additions & 0 deletions terraform/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# You need to start with a service account called "terraform" which has both the 'editor' and 'owner' basic permissions.
# This allows it to assign permissions to resources per https://cloud.google.com/iam/docs/understanding-roles
#
# To create domain-named storage buckets using terraform, you first have to verify ownership of the root domain, or
# "property", (eg octue.com) using the google search console. Once verified, you need to add the service account with
# which terraform acts ( eg [email protected] ) to Google Search Console > Settings > Users
# and Permissions, with "Owner" level permission.

resource "google_service_account" "openfast_service_service_account" {
account_id = "openfast-service"
display_name = "openfast-service"
description = "Operate the 'octue/openfast' Cloud Run service."
project = var.project
}


resource "google_service_account" "github_actions_service_account" {
account_id = "github-actions"
description = "Allow GitHub Actions to deploy code onto resources and run integration tests and jobs via reverse shelling."
display_name = "github-actions"
project = var.project
}


resource "google_service_account" "dev_cortadocodes_service_account" {
account_id = "dev-cortadocodes"
description = "Allow cortadocodes to test the cloud run instance."
display_name = "dev-cortadocodes"
project = var.project
}


resource "google_project_iam_binding" "iam_serviceaccountuser" {
project = var.project
role = "roles/iam.serviceAccountUser"
members = [
"serviceAccount:${google_service_account.openfast_service_service_account.email}",
"serviceAccount:${google_service_account.github_actions_service_account.email}",
]
}


resource "google_project_iam_binding" "pubsub_editor" {
project = var.project
role = "roles/pubsub.editor"
members = [
"serviceAccount:${google_service_account.openfast_service_service_account.email}",
"serviceAccount:${google_service_account.github_actions_service_account.email}",
"serviceAccount:${google_service_account.dev_cortadocodes_service_account.email}"
]
}


# Allows the GHA to call "namespaces get" for Cloud Run to determine the resulting run URLs of the services.
# This should also allow a service to get its own name by using:
# https://stackoverflow.com/questions/65628822/google-cloud-run-can-a-service-know-its-own-url/65634104#65634104
resource "google_project_iam_binding" "run_developer" {
project = var.project
role = "roles/run.developer"
members = [
"serviceAccount:${google_service_account.openfast_service_service_account.email}",
"serviceAccount:${google_service_account.github_actions_service_account.email}",
]
}


resource "google_project_iam_binding" "artifactregistry_writer" {
project = var.project
role = "roles/artifactregistry.writer"
members = [
"serviceAccount:${google_service_account.github_actions_service_account.email}",
]
}


resource "google_project_iam_binding" "storage_objectadmin" {
project = var.project
role = "roles/storage.objectAdmin"
members = [
"serviceAccount:${google_service_account.openfast_service_service_account.email}",
"serviceAccount:${google_service_account.github_actions_service_account.email}",
"serviceAccount:${var.project_number}@cloudbuild.gserviceaccount.com",
]
}


resource "google_project_iam_binding" "errorreporting_writer" {
project = var.project
role = "roles/errorreporting.writer"
members = [
"serviceAccount:${google_service_account.openfast_service_service_account.email}",
]
}


#resource "google_project_iam_binding" "secretmanager_secretaccessor" {
# project = var.project
# role = "roles/secretmanager.secretAccessor"
# members = [
# "serviceAccount:${google_service_account.elevations_api_service_account.email}",
# ]
#}


resource "google_iam_workload_identity_pool" "github_actions_pool" {
display_name = "github-actions-pool"
project = var.project
workload_identity_pool_id = "github-actions-pool"
}


resource "google_iam_workload_identity_pool_provider" "github_actions_provider" {
attribute_mapping = {
"attribute.actor" = "assertion.actor"
"attribute.repository" = "assertion.repository"
"attribute.repository_owner" = "assertion.repository_owner"
"google.subject" = "assertion.sub"
}
display_name = "Github Actions Provider"
project = var.project_number
workload_identity_pool_id = "github-actions-pool"
workload_identity_pool_provider_id = "github-actions-provider"

oidc {
allowed_audiences = []
issuer_uri = "https://token.actions.githubusercontent.com"
}
}

data "google_iam_policy" "github_actions_workload_identity_pool_policy" {
binding {
role = "roles/iam.workloadIdentityUser"
members = [
"principalSet://iam.googleapis.com/projects/${var.project_number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.github_actions_pool.workload_identity_pool_id}/attribute.repository_owner/${var.github_organisation}"
]
}
}

// Allow a machine under Workload Identity Federation to act as the given service account
resource "google_service_account_iam_policy" "github_actions_workload_identity_service_account_policy" {
service_account_id = google_service_account.github_actions_service_account.name
policy_data = data.google_iam_policy.github_actions_workload_identity_pool_policy.policy_data
}
98 changes: 98 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "4.53.1"
}
}
cloud {
organization = "octue"
workspaces {
name = "octue-openfast"
}
}
}


resource "google_project_service" "pub_sub" {
project = var.project
service = "pubsub.googleapis.com"

timeouts {
create = "30m"
update = "40m"
}
}


resource "google_project_service" "cloud_resource_manager" {
project = var.project
service = "cloudresourcemanager.googleapis.com"

timeouts {
create = "30m"
update = "40m"
}
}


resource "google_project_service" "iam" {
project = var.project
service = "iam.googleapis.com"

timeouts {
create = "30m"
update = "40m"
}
}


resource "google_project_service" "artifact_registry" {
project = var.project
service = "artifactregistry.googleapis.com"

timeouts {
create = "30m"
update = "40m"
}
}


resource "google_project_service" "cloud_run" {
project = var.project
service = "run.googleapis.com"

timeouts {
create = "30m"
update = "40m"
}
}


resource "google_project_service" "secret_manager" {
project = var.project
service = "secretmanager.googleapis.com"

timeouts {
create = "30m"
update = "40m"
}
}

#
#resource "google_project_service" "cloud_build" {
# project = var.project
# service = "cloudbuild.googleapis.com"
#
# timeouts {
# create = "30m"
# update = "40m"
# }
#}


provider "google" {
credentials = file(var.credentials_file)
project = var.project
region = var.region
}
17 changes: 17 additions & 0 deletions terraform/secrets.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#variable "secret_names" {
# description = "A list of secrets to be created and made accessible to the cloud run instance."
# type = list(string)
# default = [
# "neo4j-uri",
# "neo4j-username",
# "neo4j-password",
# ]
#}
#
#resource "google_secret_manager_secret" "secrets" {
# count = length(var.secret_names)
# secret_id = "${var.service_namespace}-${var.service_name}-${var.environment}-${var.secret_names[count.index]}"
# replication {
# automatic = true
# }
#}
6 changes: 6 additions & 0 deletions terraform/storage.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "google_storage_bucket" "crash_diagnostics" {
name = "${var.service_namespace}-${var.service_name}"
location = "EU"
force_destroy = true
uniform_bucket_level_access = true
}
39 changes: 39 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
variable "project" {
type = string
default = "octue-openfast"
}

variable "project_number" {
type = string
default = "86611255144"
}

variable "region" {
type = string
default = "europe-west3"
}

variable "github_organisation" {
type = string
default = "octue"
}

variable "credentials_file" {
type = string
default = "gcp-credentials.json"
}

variable "service_namespace" {
type = string
default = "octue"
}

variable "service_name" {
type = string
default = "openfast-service"
}

variable "environment" {
type = string
default = "main"
}

0 comments on commit 96dbf43

Please sign in to comment.