Accessing Google Cloud from AWS Instances

Joris Verbogt
Joris Verbogt
Oct 21 2022
Posted in Engineering & Technology

Authenticate without API keys

Accessing Google Cloud from AWS Instances

Although the Google Cloud Platform and Amazon Web Services are competing products for hosting your online services, you sometimes want to access a specific Google Cloud Service from an instance hosted in AWS.

The quickest way to connect to these services would be to generate a dedicated API server key in Google Cloud and store it inside AWS. However, in a production environment with lots of EC2 instances that need this access, this quickly becomes a nightmare to manage, as you would need to keep track of where keys are located, rotate them in time and make sure they are not leaked to unauthorized agents.

Wouldn't it be nice to use your already existing IAM roles in AWS to manage access to external services?

Luckily, Google Cloud allows federation of authentication to AWS, so you can use these roles to control access to specific services in Google Cloud.

AWS Instance Roles

Identity & Access Management (IAM) in AWS allows you to define Roles that can be assigned to EC2 instances. This Role determines what that specific instance is allowed to access. Any process or service running on that instance can then execute commands and connect to other services according to the policies belonging to the role.

As an example, let's create a very simple IAM Role that will allow us to connect to an EC2 instance via Session Manager.

First, go to IAM > Roles and select Create Role.

Select an EC2 service entity and click Next.

The policy we want to attach to these instances to allow Session Manager access is the AmazonSSMManagedInstanceCore policy.

Now, we can attach this role to any EC2 instance, and it will have the permissions defined in the AmazonSSMManagedInstanceCore policy.

Obviously, there is no way to attach access policies in Google Cloud Services to these Roles in AWS IAM. But we can define access policies for these roles in Google Cloud by using a feature called Identity Federation.

Identity Federation in Google Cloud

A more thorough explanation of this can be found in the Google Cloud documentation. Here, we will give an example for AWS federated access.

First, you must enable a couple of APIs in Google Cloud. Go to your project in Google Cloud Console and enable the following APIs:

  • Identity and Access Management (IAM)
  • Cloud Resource Manager
  • IAM Service Account Credentials
  • Security Token Service

To get the permissions that you need to configure workload identity federation, ask your administrator to grant you the following IAM roles on the project:

  • Workload Identity Pool Admin (roles/iam.workloadIdentityPoolAdmin)
  • Service Account Admin (roles/iam.serviceAccountAdmin)

Now, you need a Workload Identity Pool and a Provider, in this case, your AWS account.

Create the Pool:

Add an AWS Provider:

Keep the default mapping:

Now, in order to allow AWS access, we need to define a Service Account and add the AWS Role as a Principal to it.

Create a new Service Account:

And grant it access as an Identity Worker:

Here, you will also need to add roles to the Service Account that will allow access to whatever service inside Google Cloud you want to connect to from AWS.

And, finally, create a Principal that maps to the Service Role in AWS.

The Principal name is of the form:

principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.aws_role/arn:aws:sts::ACCOUNT_ID:assumed-role/ROLE_ID

Where PROJECT_NUMBER is your GCP Project Number (get it from IAM & Admin > Settings), POOL_ID is the ID of the GCP Identity Pool, ACCOUNT_ID is your AWS account and ROLE_ID is what you named the Role in AWS.

To do so, open the Service Account you just created, go to Permissions and click Grant Access. Create a new Principal with the format specified above, and grant it a Workload Identity User role:

You can also use gcloud:

gcloud iam service-accounts add-iam-policy-binding gcp-aws-test@your-project.iam.gserviceaccount.com \
--member=principalSet://iam.googleapis.com/projects/5432112345/locations/global/workloadIdentityPools/default-identity-pool/attribute.aws_role/arn:aws:sts::123456789012:assumed-role/TestRole \
--role=roles/iam.workloadIdentityUser \
--project your-project

Now, any instance in AWS with that Role in your account will have access to anything, in Google Cloud, that you grant the Service Account access to. With the example above it only has the permission to impersonate, you will have to add specific permissions suiting your use case.

Connecting the dots

The only thing you now need to configure your Google Cloud client applications is to tell it to use federated authentication. You do this by downloading the Service File from the Identity Pool's Connected Service Accounts:

And use that to configure your client application. The config file does not contain any keys and as such can be safely shared between your servers. It will only allow access to services for the current role of the instance the application is running on.

For example, in NodeJS you would use something like:

const webRiskServiceClient = new WebRiskServiceClient({
      projectId: projectId,
      keyFilename: keyFilename
    })

Where projectId is your GCP project name and keyFilename the location of the downloaded config JSON file.

Conclusion

The example above describes how you can quickly and easily use IAM in one cloud provider to access services in another cloud provider, without the need to store and manage server keys.

As always, we hope you liked this article and if you have anything to add, we are available via our Support Channel.

Keep up-to-date with the latest news