See documentation at https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds
-
Create a Google Workload Identity federation pool
GCP_PROJECT_ID="my-project-id" POOL_ID="my-pool-id" gcloud iam workload-identity-pools create $POOL_ID \ --project=$GCP_PROJECT_ID \ --location=global \ --display-name="My Federation Pool" \ --description="Full description"
-
Create a Workload Identity Provider for AWS. You can add attribute mappings to set the subject (identity), and any additional attributes in the Google token so you can use those in a IAM policy using
principalSet://
.When building attribute conditions and mappings keep in mind that the
arn
received in the AWS credentials will be something likearn:aws:sts::{account}:assumed-role/{role}/{session}
where{account}
is the numeric id of the AWS account,{role}
is the name of the AWS Role (aka identity) being used and{session}
is the name of the AWS session, the EC2 instance, AWS Lambda, or other AWS infrastructure component that assumed this role.By adding an attribute-condition we restrict this identity pool to only AWS Roles, and no other AWS identities (such as Users).
If you only want to allow a single AWS Role access you could use a stricter attribute-condition of
assertion.arn.startsWith('arn:aws:sts::$AWS_ACCOUNT_ID:assumed-role/$AWS_ROLE/
You could also map a value to
google.groups
so you can grant privileges to a group of identities.PROVIDER_ID="my-provider-id" AWS_ACCOUNT_ID="your-aws-account-id" # 12-digit AWS account ID PROVIDER_DISPLAY_NAME="My AWS Provider" PROVIDER_DESCRIPTION="Provider for specific AWS account" gcloud iam workload-identity-pools providers create-aws $PROVIDER_ID \ --project=$GCP_PROJECT_ID \ --location="global" \ --workload-identity-pool=$POOL_ID \ --account-id=$AWS_ACCOUNT_ID \ --display-name="$PROVIDER_DISPLAY_NAME" \ --description="$PROVIDER_DESCRIPTION" \ --attribute-condition="assertion.arn.startsWith('arn:aws:sts::${AWS_ACCOUNT_ID}:assumed-role/')" \ --attribute-mapping=" \ google.subject=assertion.arn, \ attribute.account=assertion.account, \ attribute.aws_role=assertion.arn.extract('assumed-role/{role}/'), \ attribute.aws_instance=assertion.arn.extract('assumed-role/{role_and_session}').extract('/{session}') \ "
The federated AWS identity can be used directly to access Google Cloud resources. Some scenarios might require Google Service Account impersonation which is described in the next section. For direct access follow the steps below:
- Create a storage bucket for testing
GCS_BUCKET_NAME=my-unique-bucket-name23573957 gcloud storage buckets create gs://$GCS_BUCKET_NAME \ --project=$GCP_PROJECT_ID \ --location=europe-west4
- Grant the federated AWS identity access to the storage bucket
GCP_PROJECT_NUMBER=$(gcloud projects describe $GCP_PROJECT_ID --format=value\(projectNumber\)) AWS_ROLE=my-aws-role gcloud storage buckets add-iam-policy-binding gs://$GCS_BUCKET_NAME \ --role=roles/storage.objectViewer \ --member="principalSet://iam.googleapis.com/projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/attribute.aws_role/$AWS_ROLE"
- Generate the
aws-credentials.json
config file to be used in the AWS code. Remove the--enable-imdsv2
if you want to use version 1 of the AWS Instance Metadata Service. The generated file does not contain confidential information and can be added to source control of your AWS code and deployed with that application.gcloud iam workload-identity-pools create-cred-config \ projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID \ --aws \ --enable-imdsv2 \ --output-file=aws-credentials.json
- Create a storage bucket for testing
GCS_BUCKET_NAME=my-unique-bucket-name23573957 gcloud storage buckets create gs://$GCS_BUCKET_NAME \ --project=$GCP_PROJECT_ID \ --location=europe-west4
- Create a Google Service Account
GCP_SERVICE_ACCOUNT=my-service-account gcloud iam service-accounts create $GCP_SERVICE_ACCOUNT --project=$GCP_PROJECT_ID
- Grant the Google Service account access to the storage bucket
gcloud storage buckets add-iam-policy-binding gs://$GCS_BUCKET_NAME \ --role=roles/storage.objectViewer \ --member="serviceAccount:$GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com"
- Grant the federated AWS identity access to impersonate the Google Service account
GCP_PROJECT_NUMBER=$(gcloud projects describe $GCP_PROJECT_ID --format=value\(projectNumber\)) AWS_ROLE=my-aws-role gcloud iam service-accounts add-iam-policy-binding $GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com \ --project=$GCP_PROJECT_ID \ --role=roles/iam.workloadIdentityUser \ --member="principalSet://iam.googleapis.com/projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/attribute.aws_role/$AWS_ROLE"
- Generate the
aws-sa-credentials.json
config file to be used in the AWS code. Remove the--enable-imdsv2
if you want to use version 1 of the AWS Instance Metadata Service. The generated file does not contain confidential information and can be added to source control of your AWS code and deployed with that application.gcloud iam workload-identity-pools create-cred-config \ projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID \ --service-account=$GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com \ --service-account-token-lifetime-seconds=600 \ --aws \ --enable-imdsv2 \ --output-file=aws-sa-credentials.json
This example is part of a larger serie of posts with examples of federation between different cloud environments.