Skip to content

Commit

Permalink
Fixed BitBucket deployment source.
Browse files Browse the repository at this point in the history
  • Loading branch information
gitwater committed Jul 16, 2021
1 parent f718989 commit 96d729a
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 8 deletions.
14 changes: 13 additions & 1 deletion src/paco/cftemplates/cftemplates.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,15 @@ def resource_name_filter(self, name, filter_id, hash_long_names):
elif name[-1] == '-' or name[0] == '-':
message = "Name must not begin or end with a dash."
elif filter_id in [
'IAM.Role.RoleName',
'IAM.ManagedPolicy.ManagedPolicyName']:
if len(name) > 255:
max_name_len = 255
message = "Name must not be longer than 255 characters."
elif filter_id in [
'IAM.Role.RoleName']:
if len(name) > 64:
max_name_len = 64
message = "Name must not be longer than 64 characters."
elif filter_id == 'IAM.Policy.PolicyName':
if len(name) > 128:
max_name_len = 128
Expand All @@ -336,6 +340,11 @@ def resource_name_filter(self, name, filter_id, hash_long_names):
if len(name) > 64:
max_name_len = 64
message = "CodeStar NotificationRule name must be 64 characters or less"
elif filter_id in [
'CodeStar.Connection']:
if len(name) > 32:
max_name_len = 32
message = "Name must not be longer than 64 characters."
else:
message = 'Unknown filter_id'

Expand Down Expand Up @@ -381,6 +390,9 @@ def resource_char_filter(self, ch, filter_id, remove_invalids=False):
elif filter_id in [
'CodeStar.NotificationRuleName']:
valid_ch_list = '-_ '
elif filter_id in [
'CodeStar.Connection']:
valid_ch_list = '/-'
else:
raise StackException(PacoErrorCode.Unknown, message="Invalid filter Id: "+filter_id)

Expand Down
115 changes: 110 additions & 5 deletions src/paco/cftemplates/codepipeline.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from awacs.aws import Allow, Statement, Policy, PolicyDocument, Principal, Action
from awacs.aws import Allow, Statement, Policy, PolicyDocument, Principal, Action, Condition, StringEquals, StringLike
from awacs.sts import AssumeRole
from paco import utils
from paco.cftemplates.cftemplates import StackTemplate
Expand Down Expand Up @@ -70,7 +70,8 @@


class CodePipeline(StackTemplate):
def __init__(self, stack, paco_ctx, base_aws_name, deploy_region, app_name, artifacts_bucket_name):
def __init__(self, stack, paco_ctx, base_aws_name,
deploy_region, app_name, artifacts_bucket_name):
self.pipeline = stack.resource
super().__init__(stack, paco_ctx, iam_capabilities=["CAPABILITY_NAMED_IAM"])
self.set_aws_name('CodePipeline', self.resource_group_name, self.resource.name)
Expand All @@ -87,13 +88,15 @@ def __init__(self, stack, paco_ctx, base_aws_name, deploy_region, app_name, arti
self.ecr_source_enabled = False
self.s3_source_enabled = False
self.github_source_enabled = False
self.bitbucket_source_enabled = False
self.codebuild_access_enabled = False
self.lambda_invoke_enabled = False
self.s3_deploy_enabled = False
self.manual_approval_is_enabled = False
self.s3_deploy_statements = []
self.ecs_deploy_assume_role_statement = None

self.codestar_connection_role_res = None
self.codedeploy_deploy_assume_role_statement = None
self.s3_deploy_assume_role_statement = None

Expand Down Expand Up @@ -548,6 +551,19 @@ def add_pipeline_service_role(self):
)
)

if self.bitbucket_source_enabled:
# Add Statement to allow CodeStar Connections if BitBucket source is being used
pipeline_policy_statement_list.append(
Statement(
Sid='CodeStarConnectionAssumeRole',
Effect=Allow,
Action=[
Action('sts', 'AssumeRole'),
],
Resource=[ troposphere.GetAtt(self.codestar_connection_role_res, 'Arn') ],
)
)

if self.codedeploy_deploy_assume_role_statement != None:
pipeline_policy_statement_list.append(self.codedeploy_deploy_assume_role_statement)
if self.s3_deploy_assume_role_statement != None:
Expand Down Expand Up @@ -836,6 +852,8 @@ def create_pipeline_from_sourcebuilddeploy(self, deploy_region):
)
)
elif action.type == 'BitBucket.Source':
self.bitbucket_source_enabled = True
print("BitBucket CodeStar connection update URL: https://console.aws.amazon.com/codesuite/settings/connections")
deploy_branch_name_param = self.create_cfn_parameter(
param_type='String',
name='BitBucketDeploymentBranchName',
Expand All @@ -847,16 +865,95 @@ def create_pipeline_from_sourcebuilddeploy(self, deploy_region):
bitbucket_connection_arn_res = troposphere.codestarconnections.Connection(
title="BitbucketConnection",
template=self.template,
ConnectionName="BitbucketConnection",
ConnectionName=self.create_resource_name(full_repository_id, filter_id='CodeStar.Connection', hash_long_names=True),
ProviderType="Bitbucket"
)
codestar_connection_role_name = self.get_bitbucket_codestar_connection_role_name()
self.codestar_connection_role_res = troposphere.iam.Role(
title='CodeStarConnectionRole',
template=self.template,
RoleName=codestar_connection_role_name,
AssumeRolePolicyDocument=Policy(
Version='2012-10-17',
Statement=[
Statement(
Effect=Allow,
Action=[AssumeRole],
Principal=Principal('AWS', self.account_ctx.id)
)
],
),
Policies=[
troposphere.iam.Policy(
PolicyName="CodeStarConnection",
PolicyDocument=Policy(
Version='2012-10-17',
Statement=[
Statement(
Effect=Allow,
Action=[
Action('codestar-connections', 'UseConnection')
],
Resource=[troposphere.Ref(bitbucket_connection_arn_res)],
)
]
)
),
troposphere.iam.Policy(
PolicyName="ArtifactsBucket",
PolicyDocument=Policy(
Version='2012-10-17',
Statement=[
Statement(
Sid='S3Access',
Effect=Allow,
Action=[
Action('s3', '*')
],
Resource=[
troposphere.Sub('arn:aws:s3:::${ArtifactsBucketName}/*'),
troposphere.Sub('arn:aws:s3:::${ArtifactsBucketName}')
]
),
Statement(
Sid='KMSCMK',
Effect=Allow,
Action=[
Action('kms', '*'),
],
Resource=[ troposphere.Ref(self.cmk_arn_param) ]
)
# Statement(
# Effect=Allow,
# Action=[
# Action('s3', '*')
# ],
# Resource=[
# self.artifacts_bucket_arn,
# f'{self.artifacts_bucket_arn}/*'
# ],
# ),
]
)
)
]
)

self.create_output(
title='BitBucketCodeStarConnectionRoleArn',
description="BitBucket CodeStar Connection Role ARN",
value=troposphere.GetAtt(self.codestar_connection_role_res, 'Arn'),
ref=action.paco_ref_parts + '.codestar.connection.arn'
)


bitbucket_source_action = troposphere.codepipeline.Actions(
Name='BitBucket',
ActionTypeId = troposphere.codepipeline.ActionTypeId(
Category = 'Source',
Owner = 'AWS',
Version = '1',
Provider = 'BitBucket'
Provider = 'CodeStarSourceConnection'
),
Configuration = {
'ConnectionArn': troposphere.Ref(bitbucket_connection_arn_res),
Expand All @@ -869,7 +966,7 @@ def create_pipeline_from_sourcebuilddeploy(self, deploy_region):
)
],
RunOrder = action.run_order,
#RoleArn = troposphere.Ref(self.codecommit_role_arn_param)
RoleArn = troposphere.GetAtt(self.codestar_connection_role_res, 'Arn')
)
source_stage_actions.append(bitbucket_source_action)
self.build_input_artifacts.append(
Expand Down Expand Up @@ -1226,3 +1323,11 @@ def get_codepipeline_role_arn(self):
self.account_ctx.get_id(),
self.pipeline_service_role_name
)

def get_bitbucket_codestar_connection_role_name(self):
codestar_connection_role_name = f'{self.stack.get_name(self)}-BitBucket-CodeStar-ConnectionRole'
return self.create_resource_name(codestar_connection_role_name, filter_id='IAM.Role.RoleName', hash_long_names=True)

def get_bitbucket_codestar_connection_role_arn(self):
codestar_connection_role_name = self.get_bitbucket_codestar_connection_role_name()
return f'arn:aws:iam::{self.account_ctx.get_id()}:role/{codestar_connection_role_name}'
6 changes: 4 additions & 2 deletions src/paco/stack/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -1227,9 +1227,11 @@ def add_hooks(self, hooks):
def set_termination_protection(self, protection_enabled):
self.termination_protection = protection_enabled

def get_name(self):
def get_name(self, template=None):
"Name of the stack in AWS. This can not be called until after the StackTemplate has been set."
name = '-'.join([ self.grp_ctx.get_aws_name(), self.template.aws_name ])
if template == None:
template = self.template
name = '-'.join([ self.grp_ctx.get_aws_name(), template.aws_name ])
if self.stack_suffix != None:
name = name + '-' + self.stack_suffix
new_name = self.create_stack_name(name)
Expand Down

0 comments on commit 96d729a

Please sign in to comment.