in lib/setup-builder-account-stack.ts [18:168]
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// CodeCommit repository for storing the policies
const scpRepo = new codeCommit.Repository(this, "scpRepo", {
repositoryName: StackConstants.scpRepoName,
description: StackConstants.scpRepoDesc
});
// S3 bucket for storing the policies
const scpBucket = new s3.Bucket(this, "scpBucket", {
encryption: BucketEncryption.S3_MANAGED,
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
removalPolicy: RemovalPolicy.RETAIN
});
// S3 bucket for storing the code pipeline artifacts
const scpArtifactsBucket = new s3.Bucket(this, "scpArtifactsBucket", {
encryption: BucketEncryption.S3_MANAGED,
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
removalPolicy: RemovalPolicy.RETAIN
});
// IAM role to create or attach SCP using custom lambda function
const customLambdaServiceRole = new iam.Role(this, "customLambdaServiceRole", {
assumedBy: new ServicePrincipal('lambda.amazonaws.com')
});
const inlinePolicyForLambda = new iam.PolicyStatement({
effect: Effect.ALLOW,
actions: [
"sts:AssumeRole",
"s3:List*",
"s3:Get*",
"codepipeline:GetJobDetails",
"codepipeline:PutJobSuccessResult",
"codepipeline:PutJobFailureResult"
],
resources: ["*"]
});
customLambdaServiceRole.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'))
customLambdaServiceRole.addToPolicy(inlinePolicyForLambda);
// Custom resource to create and attach the SCPs
const createAttachSCPs = new lambda.Function(this, 'createAttachSCPs', {
code: lambda.Code.fromAsset(
path.join(__dirname, 'custom_resources'),
{
exclude: ["**", "!create_and_attach_scp.py"]
}),
runtime: lambda.Runtime.PYTHON_3_8,
handler: 'create_and_attach_scp.handler',
environment: {
'DEBUG_MODE': 'true',
'ORG_ROLE': String(process.env.ORG_MANAGEMENT_ASSUMABLE_ROLE_ARN)
},
role: customLambdaServiceRole,
description: "Custom resource to create and attach the SCPs",
memorySize: 128,
timeout: cdk.Duration.seconds(60)
});
// Code pipeline role to create and attach the SCPs
const codePipelineServiceRole = new iam.Role(this, "codePipelineServiceRole", {
assumedBy: new ServicePrincipal('codepipeline.amazonaws.com')
});
const inlinePolicyForCodePipeline = new iam.PolicyStatement({
effect: Effect.ALLOW,
actions: [
"sts:AssumeRole",
"codecommit:Get*",
"codecommit:List*",
"codecommit:GitPull",
"codecommit:UploadArchive",
"lambda:Get*",
"lambda:List*",
"lambda:InvokeFunction",
"s3:Get*",
"s3:List*",
"s3:PutObject"
],
resources: ["*"]
});
codePipelineServiceRole.addToPolicy(inlinePolicyForCodePipeline);
// Code pipeline to create and attach the SCPs
const scpSourceOutput = new codePipeline.Artifact();
const pipeline = new codePipeline.Pipeline(this, "scpPipeline", {
role: codePipelineServiceRole,
artifactBucket: scpArtifactsBucket,
stages: [
{
stageName: 'Source',
actions: [
new codePipelineActions.CodeCommitSourceAction({
actionName: 'scpSource',
repository: scpRepo,
output: scpSourceOutput,
branch: 'main'
}),
]
},
{
stageName: 'Setup',
actions: [
new codePipelineActions.S3DeployAction({
actionName: 'copySCPs',
input: scpSourceOutput,
bucket: scpBucket,
extract: true
})
]
},
{
stageName: 'CreateSCPs',
actions: [
new codePipelineActions.LambdaInvokeAction({
actionName: "createSCPs",
lambda: createAttachSCPs,
userParameters: {
BucketName: scpBucket.bucketName
}
})
]
},
{
stageName: 'AttachSCPs',
actions: [
new codePipelineActions.LambdaInvokeAction({
actionName: "attachSCPs",
lambda: createAttachSCPs,
userParameters: {
BucketName: scpBucket.bucketName
}
})
]
}
]
});
// CodeCommit repository to be used
new cdk.CfnOutput(this, 'scpRepoCloneUrlGrc', {
value: scpRepo.repositoryCloneUrlGrc,
exportName: 'scpRepoCloneUrlGrc'
});
}