Aseem
Aseem

Reputation: 6787

Grant workload identity pool access to service account through terraform

How to grant access to a service account to WIF so that identity pool can impersonate a service account. I can do this through the UI by clicking on grant as shown below: enter image description here

How can this be done through terraform? Following is my current Terraform code:

resource "google_iam_workload_identity_pool" "gha-identity-pool" {
  workload_identity_pool_id = "gha-identity-pool-3"
}
    
resource "google_iam_workload_identity_pool_provider" "gha-identity-pool-provider" {
  workload_identity_pool_id          = google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id
  workload_identity_pool_provider_id = "gha-identity-pool-provider"
  display_name                       = "GHA identity pool provider"
    attribute_mapping                  = {
    "google.subject"       = "assertion.sub"
    "attribute.actor"      = "assertion.actor"
    "attribute.repository" = "assertion.repository"
  }
  oidc {
    issuer_uri = "https://token.actions.githubusercontent.com"
  }
}
    
data "google_project" "gcp_project" {}
    
resource "google_service_account_iam_member" "gha-sv-account-wif-iam-member" {
  service_account_id = var.gha_service_account_name
  role               = "roles/iam.workloadIdentityUser"
  member             = "principalSet://iam.googleapis.com/projects/${data.google_project.gcp_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id}/attribute.repository/org1/repo1"
}

Error:

google.auth.exceptions.RefreshError: ('Unable to acquire impersonated credentials: No access token or invalid expiration in response.', '{\n "error": {\n "code": 403,\n "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",\n "status": "PERMISSION_DENIED",\n "details": [\n {\n "@type": "type.googleapis.com/google.rpc.ErrorInfo",\n "reason": "IAM_PERMISSION_DENIED",\n "domain": "iam.googleapis.com",\n "metadata": {\n "permission": "iam.serviceAccounts.getAccessToken"\n }\n }\n ]\n }\n}\n')

Upvotes: 2

Views: 2386

Answers (1)

Aseem
Aseem

Reputation: 6787

Approach 1 - Using a 3rd party module

module "github-wif" {
  source = "mscribellito/workload-identity-federation/google"

  project_id = local.project_id

  pool_id     = "gha-identity-pool-8" # any name u want
  provider_id = "gha-identity-pool-provider-8" #  # any name u want

  attribute_mapping = {
    "google.subject"       = "assertion.sub"
    "attribute.actor"      = "assertion.actor"
    "attribute.aud"        = "assertion.aud"
    "attribute.repository" = "assertion.repository"
  }
  issuer_uri = "https://token.actions.githubusercontent.com"

  service_accounts = [
    {
      name           = module.service_accounts.gha_sv_account_name
      attribute      = "attribute.repository/<github_org_name>/<github_repo_name>" # org & repository name is case sensitive 
      all_identities = true
    }
  ]
}

Approach 2: Building your own WIF module using google modules

locals {
  repository_name = "Org1" # case sensitive
  github_org_name = "Repo1"  # case sensitive
}

resource "google_iam_workload_identity_pool" "gha-identity-pool" {
  workload_identity_pool_id = "gha-identity-pool-9"
}


resource "google_iam_workload_identity_pool_provider" "gha-identity-pool-provider" {
  workload_identity_pool_id          = google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id
  workload_identity_pool_provider_id = "gha-identity-pool-provider-9"
  display_name                       = "GHA identity pool provider"
  attribute_mapping                  = {
    "google.subject"       = "assertion.sub"
    "attribute.actor"      = "assertion.actor"
    "attribute.repository" = "assertion.repository"
  }
  oidc {
    issuer_uri = "https://token.actions.githubusercontent.com"
  }
}

data "google_project" "gcp_project" {}

resource "google_service_account_iam_member" "gha-sv-account-wif-tokencreator-iam-member" {
  service_account_id = var.gha_service_account_name
  role               = "roles/iam.serviceAccountTokenCreator"
  member             = "principalSet://iam.googleapis.com/projects/${data.google_project.gcp_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id}/attribute.repository/${local.github_org_name}/${local.repository_name}"
}
# For generous permissions
member = "principalSet://iam.googleapis.com/projects/${data.google_project.gcp_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id}/*"

Upvotes: 2

Related Questions