Search code examples
c#.net-coreamazon-cloudfrontaws-cdkaws-codepipeline

How can I AddToRolePolicy to ShellStep CodeBuild for cloudfront:CreateInvalidation


I'm using Amazon.CDK.Pipelines and trying to add a ShellStep to invalidate CloudFront distribution. I'm running into an issue finding how I'm able to add the role policy to the right place. At the moment I'm adding to the pipeline, but that seems to be the wrong level, but I haven't found another wayt to call AddToRolePolicy.

Please note that the pipeline is under the Amazon.CDK.Pipelines namespace and not Amazon.CDK.AWS.CodePipeline.

Here's the code I have at the moment:

            var step = new ShellStep("invalidate-cloudfront", new ShellStepProps
            {
                EnvFromCfnOutputs = new Dictionary<string, CfnOutput>
                {
                    { "DistributionId", stage.DistributionId },
                },
                Commands = new[] { "aws cloudfront create-invalidation --distribution-id ${DistributionId} --paths \"/*\"" },
            });

            pipeline.AddStage(stage, new AddStageOpts
            {
                Post = new[] { step },
            });

            pipeline.BuildPipeline();

            var distributionArn = $"arn:aws:cloudfront::{Account}:distribution/{stage.DistributionId}";
            pipeline.Pipeline.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps
            {
                Actions = new[] { "cloudfront:CreateInvalidation" },
                Resources = new[] { distributionArn },
            }));

I've tried to find another way to AddToRolePolicy on ShellStep or other constructs, but none have the interface to add a role policy.

Wondering if this is possible and how.


Solution

  • The CDK Pipelines module strives to be an abstract backend-agnostic API for defining self-mutating pipelines that deploy CDK apps with CDK. The default implementation that ships with AWS CDK uses CodePipeline and CodeBuild as the backend, but there can be others (for example, there is a CDK Pipelines backed by GitHub actions).

    For this reason, AWS-specific things like IAM features are missing from its abstract resouces like ShellStep.

    Considering your use-case is very common, CDK Pipelines also provides a CodeBuildStep that is less abstract - it is backed by a CodeBuild action.

    Since a CodeBuild action (or, more precisely, a project) can have an IAM role, CodeBuildStep does expose the grant principal you can use:

    var step = new CodeBuildStep("invalidate-cloudfront", new CodeBuildStepProps
    {
        EnvFromCfnOutputs = new Dictionary<string, CfnOutput>
        {
            { "DistributionId", stage.DistributionId },
        },
        Commands = new[] { "aws cloudfront create-invalidation --distribution-id ${DistributionId} --paths \"/*\"" },
    });
    
    ...
    
    step.grantPrincipal.addToPrincipalPolicy(new PolicyStatement(new PolicyStatementProps
    {
        Actions = new[] { "cloudfront:CreateInvalidation" },
        Resources = new[] { distributionArn },
    }));