-
Notifications
You must be signed in to change notification settings - Fork 0
/
bitbucket-oidc-advanced-template.yaml
224 lines (206 loc) · 8.3 KB
/
bitbucket-oidc-advanced-template.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
AWSTemplateFormatVersion: '2010-09-09'
Description: >
AWS CloudFormation Template for Bitbucket OIDC Authentication,
enabling secure communication between Bitbucket Pipelines and AWS.
Supports multiple repositories within a single Bitbucket workspace.
# PARAMETERS SECTION: User-configurable inputs for the template
Parameters:
WorkspaceName:
Type: String
Default: "pjv93"
Description: >
The Bitbucket workspace (organization) name.
- Example: 'pjv93'.
- IMPORTANT: Ensure this matches your Bitbucket workspace.
RepositoryUUIDs:
Type: CommaDelimitedList
Default: "123e4567-e89b-12d3-a456-426614174000,223e4567-e89b-12d3-a456-426614174001"
Description: >
A comma-separated list of Bitbucket repository UUIDs for the specified workspace.
- Example: "123e4567-e89b-12d3-a456-426614174000,223e4567-e89b-12d3-a456-426614174001".
- To locate the UUIDs in Bitbucket:
1. Navigate to **Repository settings** for each repository.
2. Go to **OpenID Connect**.
3. Copy the **UUID** listed under OpenID Connect.
Audience:
Type: String
Description: >
The audience (aud) retrieved from Bitbucket's OpenID Connect settings.
- Example: "ari:cloud:bitbucket::workspace/WORKSPACE_UUID".
- To locate the Audience in Bitbucket:
1. Navigate to **Repository settings**.
2. Go to **OpenID Connect**.
3. Copy the **Audience** value shown in the settings.
BucketName:
Type: String
Default: "MySample-Bucket"
Description: >
The name of the S3 bucket to grant access to Bitbucket pipelines.
- IMPORTANT: Ensure this bucket exists in your AWS account.
IAMRoleName:
Type: String
Default: "Bitbucket_OIDC_Role"
Description: >
Name of the IAM Role created for Bitbucket OIDC integration.
- Default: "Bitbucket_OIDC_Role".
# RESOURCES SECTION: AWS resources created by this template
Resources:
# Lambda function to process repository UUIDs and dynamically generate trust policy
TrustPolicyProcessor:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
import json
def update_assume_role_policy(role_name, workspace_name, audience, repo_patterns):
"""
Updates the AssumeRole policy for the IAM Role with Bitbucket repository trust conditions.
"""
iam = boto3.client('iam')
provider_url = f"api.bitbucket.org/2.0/workspaces/{workspace_name}/pipelines-config/identity/oidc"
# Construct the AssumeRole trust policy
trust_policy = {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": f"arn:aws:iam::{boto3.client('sts').get_caller_identity()['Account']}:oidc-provider/{provider_url}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
f"{provider_url}:aud": audience
},
"StringLike": {
f"{provider_url}:sub": repo_patterns
}
}
}]
}
# Update IAM Role with new trust policy
try:
iam.update_assume_role_policy(
RoleName=role_name,
PolicyDocument=json.dumps(trust_policy)
)
return True
except Exception as e:
print(f"Error updating trust policy: {str(e)}")
return False
def handler(event, context):
"""
AWS Lambda function entry point.
"""
try:
if event['RequestType'] in ['Create', 'Update']:
# Parameters from CloudFormation template
role_name = event['ResourceProperties']['RoleName']
workspace_name = event['ResourceProperties']['WorkspaceName']
audience = event['ResourceProperties']['Audience']
repository_uuids = event['ResourceProperties']['RepositoryUUIDs'].split(',')
# Format repository UUIDs for trust policy
repo_patterns = [
f"{{{uuid}}}:*" if not uuid.startswith("{") else f"{uuid}:*"
for uuid in repository_uuids
]
# Update IAM trust policy
success = update_assume_role_policy(role_name, workspace_name, audience, repo_patterns)
# Notify CloudFormation of the result
if success:
cfnresponse.send(event, context, cfnresponse.SUCCESS, {
'Message': 'Trust policy updated successfully'
})
else:
cfnresponse.send(event, context, cfnresponse.FAILED, {
'Message': 'Failed to update trust policy'
})
else:
# Handle Delete event or other no-op
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
print(f"Error: {e}")
cfnresponse.send(event, context, cfnresponse.FAILED, {
'Error': str(e)
})
Runtime: python3.9
Timeout: 30
# IAM Role for Lambda execution
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: AllowIAMUpdates
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:UpdateAssumeRolePolicy
- sts:GetCallerIdentity
Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:role/${IAMRoleName}'
# IAM OIDC Provider for Bitbucket
BitbucketOidcProvider:
Type: AWS::IAM::OIDCProvider
Properties:
ClientIdList:
- !Ref Audience
ThumbprintList:
- a031c46782e6e6c661cd4bd10397f7fdc7df0afe
Url: !Sub "https://api.bitbucket.org/2.0/workspaces/${WorkspaceName}/pipelines-config/identity/oidc"
# IAM Role for Bitbucket Pipelines
BitbucketOidcRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref IAMRoleName
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: !GetAtt LambdaExecutionRole.Arn
Action: sts:AssumeRole
Policies:
- PolicyName: S3AccessPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AllowS3Access
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:DeleteObject
- s3:ListBucket
Resource:
- !Sub "arn:aws:s3:::${BucketName}"
- !Sub "arn:aws:s3:::${BucketName}/*"
# Custom resource to update trust policy
TrustPolicyUpdater:
Type: Custom::TrustPolicy
Properties:
ServiceToken: !GetAtt TrustPolicyProcessor.Arn
RoleName: !Ref IAMRoleName
WorkspaceName: !Ref WorkspaceName
Audience: !Ref Audience
RepositoryUUIDs: !Join [ ",", !Ref RepositoryUUIDs ]
DependsOn: BitbucketOidcRole
# OUTPUTS SECTION: Useful information from the stack
Outputs:
IAMRoleArn:
Description: The ARN of the IAM Role for Bitbucket OIDC.
Value: !GetAtt BitbucketOidcRole.Arn
Export:
Name: BitbucketOidcRoleArn