Skip to content

Instantly share code, notes, and snippets.

@tanduong
Forked from jmahowald/README.md
Created June 1, 2022 16:58
Show Gist options
  • Save tanduong/90d2aba919fbd4dd3f49260933d8f74a to your computer and use it in GitHub Desktop.
Save tanduong/90d2aba919fbd4dd3f49260933d8f74a to your computer and use it in GitHub Desktop.
using terraform to wire GCP workload identity federation

Authenticating for bootstrap

gcloud auth application-default login A web browser should open up, asking you to authorize access .

You can set up a default tfvars for the input. For instance


project_id = "internal-lab"
aws_identity_pool_info = {
  internal-lab = {
    aws_acct_name = "sandbox-01"
    aws_acct_id   = 123456789
    role_arn      = "arn:aws:sts::123456789:assumed-role/gcp-admin"
  }
}

run terraform apply with your default gcloud creds After running in your outputs you'll have a map between an identity pool and an AWS role. We'll need the identity pool id to setup the credentials config. run terraform output and get the command to generate a config file.

You should see something like


pool_provider_info = {
  "internal-lab" = {
    "generated_cred_config_cmd" = <<-EOT
    gcloud iam workload-identity-pools create-cred-config \
       projects/1040700731286/locations/global/workloadIdentityPools/aws-internal-lab/providers/aws-sandbox-02-internal-lab  \
       --service-account=tf-sa-internal-lab@internal-lab.iam.gserviceaccount.com \
        --output-file=internal-lab.aws.config.json \
        --aws
    
    EOT
    .
    .
    .

You can then use that command to generate a config that will work with the the google-auth python package > 1.27.0 Set the environment variable to the name of the output file generated and you can use your aws credentials to login

export GOOGLE_APPLICATION_CREDENTIALS=internal-lab.aws.config.json

Note that it doesn't appear at present that terraform can use those same creds

provider "google" {
project = var.project_id
region = "us-central1"
zone = "us-central1-c"
}
resource "google_service_account" "terraform" {
for_each = var.aws_identity_pool_info
account_id = "tf-sa-${each.key}"
display_name = "Terraform Service Account for ${each.key}"
}
resource "google_project_iam_member" "terraform" {
for_each = var.aws_identity_pool_info
project = each.key
role = "roles/owner"
member = "serviceAccount:${google_service_account.terraform[each.key].email}"
}
resource "google_iam_workload_identity_pool" "aws" {
provider = google-beta
workload_identity_pool_id = "aws-${var.project_id}"
project = var.project_id
}
resource "google_iam_workload_identity_pool_provider" "aws" {
for_each = var.aws_identity_pool_info
project = each.key
provider = google-beta
workload_identity_pool_id = google_iam_workload_identity_pool.aws.workload_identity_pool_id
workload_identity_pool_provider_id = "aws-${each.value.aws_acct_name}-${each.key}"
display_name = "AWS ${each.key} ${each.value.aws_acct_name}"
description = "AWS identity pool provider for ${each.key}:${each.value.aws_acct_name}"
disabled = false
# attribute_condition = "attribute.aws_role==\"${each.value.role_arn}\""
# attribute_mapping = {
# "google.subject" = "assertion.arn"
# "attribute.aws_account" = "assertion.account"
# }
aws {
account_id = each.value.aws_acct_id
}
}
resource "google_service_account_iam_binding" "admin-account-iam" {
for_each = var.aws_identity_pool_info
service_account_id = google_service_account.terraform[each.key].name
role = "roles/iam.workloadIdentityUser"
members = [
"principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.aws.name}/attribute.aws_role/${each.value.role_arn}"
]
}
output "pool_provider_info" {
value = { for project, idp in var.aws_identity_pool_info :
project => {
idp_id = google_iam_workload_identity_pool_provider.aws[project].name
role_arn = idp.role_arn
sa_email = google_service_account.terraform[project].email
generated_cred_config_cmd = <<-EOC
gcloud iam workload-identity-pools create-cred-config \
${google_iam_workload_identity_pool_provider.aws[project].name} \
--service-account=${google_service_account.terraform[project].email} \
--output-file=${project}.aws.config.json \
--aws
EOC
}}
}
variable "project_id" {}
variable "aws_identity_pool_info" {
type = map(object({
aws_acct_id = string
aws_acct_name = string
role_arn = string
}))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment