constructor()

in lib/codepipeline/codepipeline-iam-construct.ts [20:217]


    constructor(scope: Construct, id: string, props: CodepipelineIamConstructProps) {
        super(scope, id);

        const keyArnFromKeyId = `arn:aws:kms:${props.kmsKeyRegion}:${props.devAccountId}:key/${props.kmsKeyId}`;

        // CloudFormationDeploymentRole
        const cfnDeploymentRole = new iam.Role(scope, 'CloudFormationDeploymentRole', {
            assumedBy: new iam.ServicePrincipal('cloudformation.amazonaws.com'),
            roleName: props.cfnDeployRoleName
        });

        // CloudFormationDeploymentRole policy document
        const cfnPolicyDocument = iam.PolicyDocument.fromJson({
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "iam:PassRole",
                    "Resource": `arn:aws:iam::${cdk.Aws.ACCOUNT_ID}:role/*`,
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "iam:GetRole",
                        "iam:GetRolePolicy",
                        "iam:PutRolePolicy",
                        "iam:CreateRole",
                        "iam:DeleteRole",
                        "iam:DeleteRolePolicy",
                        "iam:DetachRolePolicy",
                        "iam:AttachRolePolicy",
                        "iam:GetPolicy",
                        "iam:CreatePolicy",
                        "iam:DeletePolicy",
                        "iam:ListPolicyVersions"
                    ],
                    "Resource": [`arn:aws:iam::${cdk.Aws.ACCOUNT_ID}:role/*`,
                        `arn:aws:iam::${cdk.Aws.ACCOUNT_ID}:policy/*`],
                    "Effect": "Allow"
                },
                {
                    "Action": ["kinesis:CreateStream",
                        "kinesis:ListStreams",
                        "kinesis:DescribeStreamSummary",
                        "kinesis:StartStreamEncryption",
                        "kinesis:DeleteStream"],
                    "Resource": `arn:aws:kinesis:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:stream/*`,
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "firehose:DescribeDeliveryStream",
                        "firehose:ListDeliveryStreams",
                        "firehose:CreateDeliveryStream",
                        "firehose:DeleteDeliveryStream"
                    ],
                    "Resource": `arn:aws:firehose:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:deliverystream/*`,
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "lambda:CreateFunction",
                        "lambda:DeleteFunction"
                    ],
                    "Resource": `arn:aws:lambda:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:function:*`,
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "s3:CreateBucket",
                        "s3:DeleteBucket",
                        "s3:PutBucketTagging",
                        "s3:DeleteBucketTagging",
                        "s3:PutBucketVersioning",
                        "s3:SetBucketEncryption",
                        "s3:GetEncryptionConfiguration",
                        "s3:PutEncryptionConfiguration"
                    ],
                    "Resource": "*",
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "s3:GetBucketLocation",
                        "s3:GetObject",
                        "s3:ListBucket",
                        "s3:PutObject",
                        "s3:DeleteObject",
                        "s3:DeleteObjectVersion",
                    ],
                    "Resource": [
                        `arn:aws:s3:::${props.artifactBucketName}`,
                        `arn:aws:s3:::${props.artifactBucketName}/*`
                    ],
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "kms:DescribeKey",
                        "kms:GenerateDataKey",
                        "kms:Encrypt",
                        "kms:ReEncryptTo",
                        "kms:ReEncryptFrom",
                        "kms:Decrypt"
                    ],
                    "Resource": keyArnFromKeyId,
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "logs:CreateLogGroup",
                        "logs:DeleteLogGroup",
                        "logs:PutRetentionPolicy",
                        "logs:CreateLogStream",
                        "logs:DeleteLogStream",
                        "logs:PutLogEvents",
                        "logs:DescribeLogGroups",
                        "logs:DeleteRetentionPolicy"
                    ],
                    "Resource": `arn:aws:logs:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:log-group:*`,
                    "Effect": "Allow"
                },
                {
                    "Action": [
                        "states:CreateStateMachine",
                        "states:DeleteStateMachine",
                        "states:DescribeStateMachine",
                        "states:ListStateMachines",
                        "states:TagResource"
                    ],
                    "Resource": [`arn:aws:states:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:stateMachine:*`],
                    "Effect": "Allow"
                },
            ]
        })

        const cfnPolicy = new iam.Policy(scope, 'CrossAccountCfnDeployPolicy', {
            document: cfnPolicyDocument,
        });
        cfnPolicy.attachToRole(cfnDeploymentRole)

        // CodePipeline Cross-Account Role
        const codePipelineCrossAccountRole = new iam.Role(scope, 'CodePipelineCrossAccountRole', {
            assumedBy: iam.Role.fromRoleArn(this, 'DevAccountRootPrincipal', `arn:aws:iam::${props.devAccountId}:root/`),
            roleName: props.codePipelineRoleName
        });

        // Add s3 permissions
        codePipelineCrossAccountRole.addToPolicy(
            new iam.PolicyStatement({
                effect: Effect.ALLOW,
                actions: [
                    "s3:GetBucketLocation",
                    "s3:GetObject",
                    "s3:ListBucket",
                    "s3:PutObject",
                    "s3:DeleteObject",
                    "s3:DeleteObjectVersion",
                ],
                resources: [
                    `arn:aws:s3:::${props.artifactBucketName}`,
                    `arn:aws:s3:::${props.artifactBucketName}/*`
                ],
            }))

        // Add kms permissions
        codePipelineCrossAccountRole.addToPolicy(
            new iam.PolicyStatement({
                effect: Effect.ALLOW,
                actions: [
                    "kms:DescribeKey",
                    "kms:GenerateDataKey",
                    "kms:Encrypt",
                    "kms:ReEncryptFrom",
                    "kms:ReEncryptTo",
                    "kms:Decrypt"
                ],
                resources: [keyArnFromKeyId],
            }))

        // Add cfn permissions
        codePipelineCrossAccountRole.addToPolicy(
            new iam.PolicyStatement({
                effect: Effect.ALLOW,
                actions: ["cloudformation:DescribeStacks",
                    "cloudformation:CreateStack",
                    "cloudformation:UpdateStack",],
                resources: [`arn:aws:cloudformation:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:stack/KinesisApplicationStack/*`,
                    `arn:aws:cloudformation:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:stack/IntTestSfnStack/*`],
            }))

        // Add passrole permissions
        codePipelineCrossAccountRole.addToPolicy(
            new iam.PolicyStatement({
                effect: Effect.ALLOW,
                actions: ["iam:PassRole"],
                resources: [cfnDeploymentRole.roleArn],
            }))
    }