This guide will explain what is required to create a Bitbucket OpenID Connect (OIDC) provider in AWS CDK and includes a Bitbucket pipeline example on how to authenticate to AWS and access resources.
If you’re looking to configure OpenID Connect for GitHub, then read this article.
Table of Contents
What is a Bitbucket OpenID Connect provider (OIDC)?
It’s an identity provider for BitBucket which uses the OpenID Connect protocol and can be set up on an AWS Account to establish trust between the account and your Bitbucket repository.
The advantage is that it allows you to access resources in AWS using an IAM role instead of using long-lived AWS credentials.
How to configure OpenID Connect for Bitbucket in AWS CDK
1. Create the Bitbucket OIDC provider
We’ll start by creating the OpenIdConnectProvider
for Bitbucket:
const bitbucketDomain =
'api.bitbucket.org/2.0/workspaces/<WORKSPACE>/pipelines-config/identity/oidc';
const bitbucketAudience =
'ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1';
const bitbucketProvider = new iam.OpenIdConnectProvider(
this,
'bitbucketProvider',
{
url: `https://${bitbucketDomain}`,
clientIds: [bitbucketAudience],
}
);
To create the OIDC provider resource for Bitbucket we need to fill the following properties:
url
:api.bitbucket.org/2.0/workspaces/<WORKSPACE>/pipelines-config/identity/oidc
. Here you insert the Provider URL of the OpenID Connect URL used for authentication requests. Note: make sure to replace<WORKSPACE>
with your own unique workspace name.clientIds
:ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1
. This is the audience ID that is issued by the Identity Provider for your app.
You can find both the Provider URL and Audience ID in the OpenID Connect tab of your Bitbucket repository settings. For more details, check the official Bitbucket support page.
2. Create an IAM role with a WebIdentityPrincipal
Now we need to create an IAM role that is needed so we’ll be able to authenticate against the Bitbucket OIDC provider.
new iam.Role(this, 'exampleBitbucketDeployRole', {
assumedBy: new iam.WebIdentityPrincipal(
bitbucketProvider.openIdConnectProviderArn,
conditions
),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
],
roleName: 'exampleBitbucketDeployRole',
description:
'This role is used via Bitbucket pipelines to deploy with AWS CDK or Terraform on the customers AWS account',
maxSessionDuration: cdk.Duration.hours(2),
});
To enable the IAM role to authenticate against the OIDC provider, we need to add the property iam.WebIdentityPrincipal
and add the bitbucketProvider.openIdConnectProviderArn
from the bitbucketProvider
we created in the previous step.
The IAM role itself has no permissions by default, so we add a new property managedPolicies
, and assign an AWS managed policy.
In this example, we apply the managed policy AdministratorAccess
but you can limit the role’s privileges by assigning a custom or managed policy that contains fewer privileges.
The property maxSessionDuration
sets a limit on how long the AWS STS credentials can be used at a time before expiring. In this case, the duration of the session with the STS credentials is set to 2 hours.
3. Create the condition for the IAM role and assign it to the WebIdentityPrincipal
In the previous part, we created the IAM role and as you can see we added conditions to the assumedBy
property:
assumedBy: new iam.WebIdentityPrincipal(bitbucketProvider.openIdConnectProviderArn, conditions),
Now we’ll focus on creating the condition which will be attached to the iam.WebIdentityPrincipal
. The condition is important because it allows us to limit the assumed role only to the Bitbucket repositories within the workspace.
We declare the following condition:
const bitbucketAudience =
'ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1';
// grant only requests coming from a specific Bitbucket workspace.
const conditions: iam.Conditions = {
StringEquals: {
[`${bitbucketDomain}:aud`]: bitbucketAudience,
},
};
The actual policy for the Web Identity will look like this when we synthesize the template in AWS CDK:
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"api.bitbucket.org/2.0/workspaces/<WORKSPACE>/pipelines-config/identity/oidc:aud": "ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1"
}
},
"Effect": "Allow",
"Principal": {
"Federated": {
"Ref": "bitbucketProviderE25A039A"
}
}
}
],
"Version": "2012-10-17"
},
4. Set up the bitbucket-pipelines.yml
file
In order to create a CI/CD pipeline in Bitbucket, all you have to do is create a bitbucket-pipelines.yml
at the root of your repository.
For this example, we’ll show how to set up the AWS credentials which we use to authenticate with the Bitbucket OIDC provider we created in AWS CDK at the beginning of this post.
image: node:16.3.0
pipelines:
branches:
main:
- step:
name: cdk deploy using oidc
oidc: true
script:
- export AWS_REGION=eu-west-1
- export AWS_ROLE_ARN=arn:aws:iam::012345678901:role/exampleBitbucketDeployRole
- export AWS_WEB_IDENTITY_TOKEN_FILE=$(pwd)/web-identity-token
- echo $BITBUCKET_STEP_OIDC_TOKEN > $(pwd)/web-identity-token
- cdk deploy --app "ts-node openid-connect-bitbucket/main.ts" "*bitbucket-oidc" --require-approval never
If you plan on using this example then make sure to change the following values:
AWS_ROLE_ARN=arn:aws:iam::012345678901:role/exampleBitbucketDeployRole
. Change the AWS account id of the role ARN which matches the account id where you deployed the Bitbucket OIDC provider.AWS_REGION=eu-west-1
. Change this to the region where you wish to run yourcdk deploy
command.cdk deploy --app "ts-node openid-connect-bitbucket/main.ts" "*bitbucket-oidc" --require-approval never
. This deploys the AWS CDK stack that is hosted on myaws-cdk-examples
GitHub repository. Change this to your own custom AWS CDK stack.
Note: If you need more details I highly suggest reading the official Bitbucket documentation on how to set up the credentials for the pipeline.
Conclusion
You were able to successfully set up a Bitbucket OpenID Connect provider (OIDC) using AWS CDK TypeScript.
Additionally, you’ve also managed to test the OIDC connection in bitbucket pipelines by setting up and configuring the bitbucket-pipelines.yml
file.
Everything that you’ve just built by following this article can also be found as a fully working example on my GitHub repository.
Elevate Your AWS CDK App with Expert Review & Guidance
Unlock the full potential of your AWS CDK app with our Expert AWS CDK App Code Review Service, conveniently delivered through AWS IQ.
Gain invaluable insights, minimize risks, and set a clear path forward for your project’s success.