From 630e72828d2af57bfed825296c9718f13d875e93 Mon Sep 17 00:00:00 2001 From: Lucas Pickering Date: Wed, 13 Sep 2023 11:51:32 -0400 Subject: [PATCH] debuggery --- .github/workflows/deploy.yml | 7 ++-- deploy/terraform/core/.terraform.lock.hcl | 21 ++++++++++ deploy/terraform/core/github.tf | 18 ++++---- deploy/terraform/core/keskne/README.md | 38 +++++++++++++++++ deploy/terraform/core/keskne/main.tf | 48 +++++++++++++++++++++ deploy/terraform/core/keskne/outputs.tf | 9 ++++ deploy/terraform/core/keskne/variables.tf | 51 +++++++++++++++++++++++ deploy/terraform/core/variables.tf | 12 ------ 8 files changed, 178 insertions(+), 26 deletions(-) create mode 100644 deploy/terraform/core/keskne/README.md create mode 100644 deploy/terraform/core/keskne/main.tf create mode 100644 deploy/terraform/core/keskne/outputs.tf create mode 100644 deploy/terraform/core/keskne/variables.tf diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ae6db145..9d2f5a49 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -49,14 +49,15 @@ jobs: - name: Google Cloud auth uses: google-github-actions/auth@v0 with: - service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }} - workload_identity_provider: ${{ secrets.GOOGLE_WORKLOAD_ID_PROVIDER }} + # Auth with the *keskne* project because that's where the cluster is hosted + service_account: ${{ secrets.KESKNE_GOOGLE_SERVICE_ACCOUNT }} + workload_identity_provider: ${{ secrets.KESKNE_GOOGLE_WORKLOAD_ID_PROVIDER }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v1.1.1 - name: Save kubeconfig - run: gcloud container clusters get-credentials --project keskne ${{ vars.CLUSTER_NAME }} --location ${{ vars.CLUSTER_LOCATION }} + run: gcloud container clusters get-credentials ${{ vars.KESKNE_CLUSTER_NAME }} --location ${{ vars.KESKNE_CLUSTER_LOCATION }} - name: Helm deploy # The two TLS secrets have to be put in files because they're multi-line diff --git a/deploy/terraform/core/.terraform.lock.hcl b/deploy/terraform/core/.terraform.lock.hcl index b78dae4b..43c42b66 100644 --- a/deploy/terraform/core/.terraform.lock.hcl +++ b/deploy/terraform/core/.terraform.lock.hcl @@ -1,6 +1,27 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/hashicorp/github" { + version = "5.36.0" + hashes = [ + "h1:+hZ4h8O3QfQFk/fmWftQJVnpNP3xqoCzgf2QlhqTyeg=", + "zh:16a8018d4bf8febca9a5482ce66559646f760184e89bb39ed34592451681a252", + "zh:1c2781f9938df9ef571d90281c4319fbc1d961afdce6aec4a8faac12da16871a", + "zh:48b2155411f1e6dd996ab4abf3846decf6d1404d86ceeb5652e4a982195de4b9", + "zh:4f21a97e4d9e5569373ba59a7cf564ab6db9cdea1930f760179ac349f2d03030", + "zh:57d39fb320b3f3ffc55d80ae8dd205a2cfc7d9fafb270a371500370f526e0baa", + "zh:89b444491a25d789288a80a32531991a29565b6873af5f37face588d04fcff35", + "zh:8db5d4bdc47bb0fd71971954bb0c22dcd25c9550b1598f5075fd0a92c040d7ac", + "zh:95913de9a0c348bdc0cc1fa727fa8f4c092a311a56981ab7c48959a82a363a70", + "zh:9e9aeac23cec279cc0eea6e21eeb8977e291ed9cf831a8d09a147eeda4ef22d8", + "zh:bc7a19a4cacb20e26a4021942acefa7b1a05de22250651ef5e3fb36272a5e85b", + "zh:c68d27aedec0e6f6551e4db79cc86b6098c626594272265bb3d84bb0bdf99b47", + "zh:ca37ae109cf7537b1cb188244ee028df3da34db803a10e9d64d44da9d88b02e7", + "zh:db1ac55a2b2d15678845f5a3cde8fae75ef6b67d1830e37488a9e65fbd2caf09", + "zh:f14b1b46320455edaed88b74c7324ecea43b5daf382c4cd891fd88addb8b8940", + ] +} + provider "registry.terraform.io/hashicorp/google" { version = "4.58.0" constraints = ">= 3.64.0, ~> 4.0, < 5.0.0" diff --git a/deploy/terraform/core/github.tf b/deploy/terraform/core/github.tf index f83a3a7e..5ddbccff 100644 --- a/deploy/terraform/core/github.tf +++ b/deploy/terraform/core/github.tf @@ -2,26 +2,22 @@ locals { # Use a mapping so we don't have to repeat a ton of boilerplate - variables = { - CLUSTER_NAME = var.kubernetes_cluster_name - CLUSTER_LOCATION = var.kubernetes_cluster_location - } secrets = { GOOGLE_WORKLOAD_ID_PROVIDER = module.oidc.provider_name GOOGLE_SERVICE_ACCOUNT = google_service_account.service_account.email } } -resource "github_actions_variable" "variables" { - for_each = local.variables - repository = var.github_repository - variable_name = each.key - value = each.value -} - resource "github_actions_secret" "secrets" { for_each = local.secrets repository = var.github_repository secret_name = each.key plaintext_value = each.value } + +# Create a service account for the keskne project, to access GKE +module "keskne" { + source = "./keskne" + github_repository = "beta-spray" + service_account_id = "beta-spray-github-ci-sa" +} diff --git a/deploy/terraform/core/keskne/README.md b/deploy/terraform/core/keskne/README.md new file mode 100644 index 00000000..33c7a8ec --- /dev/null +++ b/deploy/terraform/core/keskne/README.md @@ -0,0 +1,38 @@ +# Keskne GitHub CI Terraform Module + +A module to help access the Keskne GKE cluster from GitHub CI. This creates the following resources: + +- Service account +- Workload ID provider that allows GitHub to act as the service account (see [gh-oidc module](https://registry.terraform.io/modules/terraform-google-modules/github-actions-runners/google/latest/submodules/gh-oidc)) +- Repository-wide GitHub variables containing the cluster name/location (for the `gcloud` command) +- Repository-wide GitHub secrets containing the service account/workload provider ID + +## Usage + +This requires that you already have the Google Terraform provider configured (with access to Keskne), as well as the GitHub Terraform provider authenticated to the repository's owner. + +Add this to your Terraform, replacing the obvious parts: + +``` +module "keskne" { + source = "./keskne" # TODO update + github_repository = "my-repository" + service_account_id = "my-repository-github-ci-sa" +} +``` + +Then add this to your deployment CI: + +```yaml +- name: Google Cloud auth + uses: google-github-actions/auth@v0 + with: + service_account: ${{ secrets.KESKNE_GOOGLE_SERVICE_ACCOUNT }} + workload_identity_provider: ${{ secrets.KESKNE_GOOGLE_WORKLOAD_ID_PROVIDER }} +- name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@v1.1.1 +- name: Save kubeconfig + run: gcloud container clusters get-credentials ${{ vars.KESKNE_CLUSTER_NAME }} --location ${{ vars.KESKNE_CLUSTER_LOCATION }} +``` + +The names of these GitHub variables are configurable in the module variables. diff --git a/deploy/terraform/core/keskne/main.tf b/deploy/terraform/core/keskne/main.tf new file mode 100644 index 00000000..dd8f103d --- /dev/null +++ b/deploy/terraform/core/keskne/main.tf @@ -0,0 +1,48 @@ +# Create a new service account to access GKE creds +resource "google_service_account" "service_account" { + # Make sure to override project from the parent provider + project = var.gcp_project_id + account_id = var.service_account_id + display_name = "${var.github_repository} GitHub CI Service Account" + description = "Service account for ${var.github_repository} to access GKE creds from GitHub CI" +} + +module "oidc" { + source = "terraform-google-modules/github-actions-runners/google//modules/gh-oidc" + project_id = var.gcp_project_id + pool_id = "github-pool" + provider_id = "github-provider" + sa_mapping = { + (google_service_account.service_account.account_id) = { + sa_name = google_service_account.service_account.name + attribute = "attribute.repository/${var.github_repository}" + } + } +} + +# Create variables/secrets in Github to access the SA and cluster + +locals { + variables = { + (var.github_cluster_name_variable) = var.kubernetes_cluster_name + (var.github_cluster_location_variable) = var.kubernetes_cluster_location + } + secrets = { + (var.github_service_account_secret) = module.oidc.provider_name + (var.github_workload_id_provider_secret) = google_service_account.service_account.email + } +} + +resource "github_actions_variable" "variables" { + for_each = local.variables + repository = var.github_repository + variable_name = each.key + value = each.value +} + +resource "github_actions_secret" "secrets" { + for_each = local.secrets + repository = var.github_repository + secret_name = each.key + plaintext_value = each.value +} diff --git a/deploy/terraform/core/keskne/outputs.tf b/deploy/terraform/core/keskne/outputs.tf new file mode 100644 index 00000000..fc31bd37 --- /dev/null +++ b/deploy/terraform/core/keskne/outputs.tf @@ -0,0 +1,9 @@ +output "service_account_id" { + description = "ID of the created service account" + value = google_service_account.service_account.account_id +} + +output "service_account_email" { + description = "Email of the created service account" + value = google_service_account.service_account.email +} diff --git a/deploy/terraform/core/keskne/variables.tf b/deploy/terraform/core/keskne/variables.tf new file mode 100644 index 00000000..7732bd18 --- /dev/null +++ b/deploy/terraform/core/keskne/variables.tf @@ -0,0 +1,51 @@ +variable "gcp_project_id" { + description = "ID of the Keskne GCP project" + type = string + default = "keskne-347510" +} + +variable "kubernetes_cluster_name" { + description = "Name of the Kubernetes cluster (within GCP) that we'll deploy to" + type = string + default = "keskne-gke" +} + +variable "kubernetes_cluster_location" { + description = "Location (region or zone ) of the Kubernetes cluster (within GCP) that we'll deploy to" + type = string + default = "us-east1-c" +} + +variable "github_cluster_name_variable" { + description = "Name of the variable to create in GitHub that will hold the Keskne cluster name" + type = string + default = "KESKNE_CLUSTER_NAME" +} + +variable "github_cluster_location_variable" { + description = "Name of the variable to create in GitHub that will hold the Keskne cluster location" + type = string + default = "KESKNE_CLUSTER_LOCATION" +} + +variable "github_service_account_secret" { + description = "Name of the secret to create in GitHub that will hold the service account email" + type = string + default = "KESKNE_GOOGLE_SERVICE_ACCOUNT" +} + +variable "github_workload_id_provider_secret" { + description = "Name of the secret to create in GitHub that will hold the workload ID provider" + type = string + default = "KESKNE_GOOGLE_WORKLOAD_ID_PROVIDER" +} + +variable "github_repository" { + description = "ID of the *consuming* GitHub repository, e.g. LucasPickering/keskne" + type = string +} + +variable "service_account_id" { + description = "ID of the service account to create in the Keskne project" + type = string +} diff --git a/deploy/terraform/core/variables.tf b/deploy/terraform/core/variables.tf index b677788a..72bce54e 100644 --- a/deploy/terraform/core/variables.tf +++ b/deploy/terraform/core/variables.tf @@ -30,18 +30,6 @@ variable "gcp_region" { type = string } -variable "kubernetes_cluster_name" { - description = "Name of the Kubernetes cluster (within GCP) that we'll deploy to" - type = string - default = "keskne-gke" -} - -variable "kubernetes_cluster_location" { - description = "Location (region or zone ) of the Kubernetes cluster (within GCP) that we'll deploy to" - type = string - default = "us-east1-c" -} - variable "static_assets_bucket" { description = "Name of storage bucket to store static assets" default = "beta-spray-static"