Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions infra/terraform/bootstrap/identity/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ provider "google" { project = local.project.project_id }
module "bootstrap_identity" {
source = "../../modules/foundations/bootstrap_identity"

project_id = local.project.project_id
github_owner = split("/", local.project.github_repository)[0]
github_repo = split("/", local.project.github_repository)[1]
allowed_ref = "refs/heads/main"
environment = local.environment.environment
service_account_id = "github-terraform-sandbox"
project_roles = var.project_roles
project_id = local.project.project_id
github_owner = split("/", local.project.github_repository)[0]
github_repo = split("/", local.project.github_repository)[1]
github_repositories = toset([local.project.github_repository, "sailing-together/MemoryDirector"])
allowed_ref = "refs/heads/main"
environment = local.environment.environment
service_account_id = "github-terraform-sandbox"
project_roles = var.project_roles
}
4 changes: 2 additions & 2 deletions infra/terraform/modules/base/github_oidc_provider/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ resource "google_iam_workload_identity_pool" "github" {
project = var.project_id
workload_identity_pool_id = var.pool_id
display_name = "GitHub Actions"
description = "GitHub Actions OIDC identities for ${var.github_repository}."
description = "GitHub Actions OIDC identities for ${join(", ", tolist(var.github_repositories))}."
}

resource "google_iam_workload_identity_pool_provider" "github" {
project = var.project_id
workload_identity_pool_id = google_iam_workload_identity_pool.github.workload_identity_pool_id
workload_identity_pool_provider_id = "github"
display_name = "GitHub Actions OIDC"
attribute_condition = "assertion.repository == '${var.github_repository}' && assertion.ref == '${var.allowed_ref}' && assertion.environment == '${var.environment}'"
attribute_condition = "assertion.repository in ${jsonencode(tolist(var.github_repositories))} && assertion.ref == '${var.allowed_ref}' && assertion.environment == '${var.environment}'"
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.repository" = "assertion.repository"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
output "name" { value = google_iam_workload_identity_pool.github.name }
output "provider_name" { value = google_iam_workload_identity_pool_provider.github.name }
output "attribute_condition" { value = google_iam_workload_identity_pool_provider.github.attribute_condition }
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
variable "project_id" { type = string }
variable "pool_id" { type = string }
variable "github_repository" { type = string }
variable "github_repositories" { type = set(string) }
variable "allowed_ref" { type = string }
variable "environment" { type = string }
18 changes: 12 additions & 6 deletions infra/terraform/modules/foundations/bootstrap_identity/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ resource "google_project_service" "identity" {
module "github_oidc" {
source = "../../base/github_oidc_provider"

project_id = var.project_id
pool_id = "github-actions"
github_repository = "${var.github_owner}/${var.github_repo}"
allowed_ref = var.allowed_ref
environment = var.environment
project_id = var.project_id
pool_id = "github-actions"
github_repositories = var.github_repositories
allowed_ref = var.allowed_ref
environment = var.environment

depends_on = [google_project_service.identity]
}
Expand All @@ -49,9 +49,15 @@ module "terraform_deployer" {
}

resource "google_service_account_iam_member" "github_workload_identity_user" {
for_each = var.github_repositories
service_account_id = module.terraform_deployer.name
role = "roles/iam.workloadIdentityUser"
member = "principalSet://iam.googleapis.com/${module.github_oidc.name}/attribute.repository/${var.github_owner}/${var.github_repo}"
member = "principalSet://iam.googleapis.com/${module.github_oidc.name}/attribute.repository/${each.value}"
}

moved {
from = google_service_account_iam_member.github_workload_identity_user
to = google_service_account_iam_member.github_workload_identity_user["afaryy/MemoryDirector"]
}

resource "google_project_iam_member" "terraform_deployer" {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
output "github_repository" { value = "${var.github_owner}/${var.github_repo}" }
output "github_repositories" { value = tolist(var.github_repositories) }
output "allowed_ref" { value = var.allowed_ref }
output "environment" { value = var.environment }
output "service_account_email" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,38 @@ run "restricts_github_federation_to_the_sandbox_repository_and_main" {
command = plan

variables {
project_id = "memory-director-sandbox"
github_owner = "afaryy"
github_repo = "MemoryDirector"
allowed_ref = "refs/heads/main"
environment = "sandbox"
service_account_id = "github-terraform-sandbox"
project_id = "memory-director-sandbox"
github_owner = "afaryy"
github_repo = "MemoryDirector"
github_repositories = ["afaryy/MemoryDirector", "sailing-together/MemoryDirector"]
allowed_ref = "refs/heads/main"
environment = "sandbox"
service_account_id = "github-terraform-sandbox"
}

assert {
condition = output.github_repository == "afaryy/MemoryDirector"
error_message = "The deployment identity must be restricted to the Memory Director repository."
}

assert {
condition = toset(output.github_repositories) == toset(["afaryy/MemoryDirector", "sailing-together/MemoryDirector"])
error_message = "The transitional WIF policy must trust exactly the current and target Memory Director repositories."
}

assert {
condition = module.github_oidc.attribute_condition == "assertion.repository in [\"afaryy/MemoryDirector\",\"sailing-together/MemoryDirector\"] && assertion.ref == 'refs/heads/main' && assertion.environment == 'sandbox'"
error_message = "WIF must restrict both allowed repositories to the main ref and sandbox environment."
}

assert {
condition = toset(keys(google_service_account_iam_member.github_workload_identity_user)) == toset([
"afaryy/MemoryDirector",
"sailing-together/MemoryDirector",
])
error_message = "Only the current and target repositories may impersonate the Terraform service account during the transition."
}

assert {
condition = output.allowed_ref == "refs/heads/main"
error_message = "The deployment identity must be restricted to the approved main ref."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
variable "project_id" { type = string }
variable "github_owner" { type = string }
variable "github_repo" { type = string }
variable "github_repositories" { type = set(string) }
variable "allowed_ref" { type = string }
variable "environment" { type = string }
variable "service_account_id" { type = string }
Expand Down
Loading