Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pipelines] how to add notifications to a CDK pipeline? or: expose underlying CodePipeline object #9710

Open
1 of 2 tasks
cprice404-aws opened this issue Aug 14, 2020 · 14 comments
Labels
@aws-cdk/pipelines CDK Pipelines library effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2

Comments

@cprice404-aws
Copy link

cprice404-aws commented Aug 14, 2020

As far as I can tell, there is no way with the current CDK pipeline API to add codestarnotifications to the underlying CodePipeline, because there is no way to get the ARN of the CodePipeline.

The CdkPipeline has a private variable that holds the reference to the CodePipeline, but we can't access it. I imagine that it would be useful for developers to have access to this for many other reasons as well.

Use Case

There is no way to set up notifications for a CDK pipeline.

Proposed Solution

Change CdkPipeline private readonly _pipeline member variable to public.

Other

  • 👋 I may be able to implement this feature request
  • ⚠️ This feature might incur a breaking change

This is a 🚀 Feature Request

@cprice404-aws cprice404-aws added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Aug 14, 2020
@github-actions github-actions bot added the @aws-cdk/pipelines CDK Pipelines library label Aug 14, 2020
@cprice404-aws
Copy link
Author

I did a hacky thing and used the typescript (<any>cdkPipelineInstance)._pipeline.pipelineArn to access the private variable and see what the arn of the CodePipeline was (since it doesn't show up in the console UI) - it looks like it's deterministic based on the Name that I pass to the CdkPipeline constructor, so maybe that'll be a reasonable workaround for now. It still feels like exposing the pipelineArn would be useful. Docs / examples on recommended way to set up notifications would be super useful, though.

@rix0rrr rix0rrr added effort/small Small work item – less than a day of effort p2 labels Aug 17, 2020
tomas-mazak added a commit to tomas-mazak/aws-cdk that referenced this issue Aug 25, 2020
CdkPipeline does not expose all of the CodePipeline pipeline properties,
for example, custom artifactBucket cannot be provided. This change
allows providing a CodePipeline pipeline instance as a prop, rather than
exposing all the missing settings individually. Closes aws#9794. Closes aws#9710.
tomas-mazak added a commit to tomas-mazak/aws-cdk that referenced this issue Aug 25, 2020
CdkPipeline does not expose all of the CodePipeline pipeline properties,
for example, custom artifactBucket cannot be provided. This change
allows providing a CodePipeline pipeline instance as a prop, rather than
exposing all the missing settings individually. Closes aws#9794. Closes aws#9710.
@SomayaB SomayaB added in-progress This issue is being actively worked on. and removed needs-triage This issue or PR still needs to be triaged. labels Aug 31, 2020
@jaidisido
Copy link

Any update on this please? The only workaround at the moment is to manually build the pipeline arn based on the deterministic name which is not ideal

@rix0rrr rix0rrr removed their assignment Jun 3, 2021
@brno32
Copy link

brno32 commented Jun 14, 2021

I need this as well

@wilhen01
Copy link
Contributor

You can get codestar notifications working with CDK pipelines using the below code snippet. pipeline.codePipeline exposes the underlying CodePipeline object.

import * as pipelines from '@aws-cdk/pipelines';
import { DetailType, NotificationRule } from '@aws-cdk/aws-codestarnotifications';
import { Topic } from '@aws-cdk/aws-sns';
import { Construct, Fn, Stack, StackProps } from '@aws-cdk/core';

const pipeline = new pipelines.CdkPipeline(this, 'Deployer', {
      cloudAssemblyArtifact,
      sourceAction,
      synthAction,
    });
    
const slackNotificationTopicArn = Fn.importValue(Exports.SlackStatusNotificationsTopic);
const targetTopic = Topic.fromTopicArn(this, 'topic', slackNotificationTopicArn);

new NotificationRule(this, 'Notification', {
      detailType: DetailType.BASIC,
      events: ['codepipeline-pipeline-pipeline-execution-failed'],
      source: pipeline.codePipeline,
      targets: [targetTopic],
    });

@TomaszSzusterTR
Copy link

The same applies to the pipelines from aws_cdk, although there is no codePipeline object available thus setting up notification fails miserably.

from aws_cdk import pipelines
from aws_cdk.aws_codestarnotifications import NotificationRule, DetailType
codepipeline = pipelines.CodePipeline(...)

        NotificationRule(
            self,
            "codepipeline_notifications",
            detail_type=DetailType.BASIC,
            events=[
                "codepipeline-pipeline-pipeline-execution-failed",
                "codepipeline-pipeline-action-execution-failed",
                "codepipeline-pipeline-stage-execution-failed",
                "codepipeline-pipeline-manual-approval-failed",
                "codepipeline-pipeline-manual-approval-needed",
            ],
            source=codepipeline,
            targets=[notifications_sns_topic],
        )

raise JSIIError(resp.error) from JavaScriptError(resp.stack) jsii.errors.JSIIError: props.source.bindAsNotificationRuleSource is not a function

@samlaf
Copy link

samlaf commented Oct 6, 2021

@TomaszSzusterTR could the error be because you forgot your brackets around your props?
NotificationRule's constructor is constructor(scope: constructs.Construct, id: string, props: NotificationRuleProps), so it should be called as

NotificationRule(self, "codepipeline_notifications", {
    detail_type=DetailType.BASIC,
    events=[
        "codepipeline-pipeline-pipeline-execution-failed",
        "codepipeline-pipeline-action-execution-failed",
        "codepipeline-pipeline-stage-execution-failed",
        "codepipeline-pipeline-manual-approval-failed",
        "codepipeline-pipeline-manual-approval-needed",
    ],
    source=codepipeline.pipeline,
    targets=[notifications_sns_topic],
})

UPDATE: ah I just noticed your first comment. source should be codepipeline.pipeline, which refers to the actual codepipeline object (codepipeline is only a cdk-pipeline construct).

@federicobarera
Copy link

federicobarera commented Oct 12, 2021

@TomaszSzusterTR

EDIT 2:

Adding pipeline.buildPipeline() between the CodePipeline and the Notification creates the notification correctly.

import {
  CodePipeline,
} from '@aws-cdk/pipelines';

const pipeline = new CodePipeline(this, 'Pipeline', {
      synth,
      pipelineName: stackName
    });

pipeline.buildPipeline()

const rule = new NotificationRule(this, 'Notification', {
      detailType: DetailType.BASIC,
      events: [
        'codepipeline-pipeline-pipeline-execution-started',
        'codepipeline-pipeline-pipeline-execution-failed',
        'codepipeline-pipeline-pipeline-execution-succeeded'
      ],
      source: pipeline.pipeline,
      targets: [targetTopic]
    });

@samlaf
Copy link

samlaf commented Oct 12, 2021

@federicobarera where did you add the pipeline.buildPipeline()? In between the pipeline and the rule?
I did the same and it works for me, and the NotificationRule does get created... so not sure what's happening to you.

On the other end, it seems like the cdk is forgetting to give permissions to the NotificationRule to publish to the sns topic. I am seeing unreachable in the console:
image

After some research it seems that I need to add the IAM policy to the notificationRule:
https://docs.aws.amazon.com/dtconsole/latest/userguide/troubleshooting.html#troubleshooting-resource-unavailable
https://docs.aws.amazon.com/dtconsole/latest/userguide/set-up-sns.html

and the cdk NotificationRule does not yet offer a simple topic.grantPublish(notification.PrincipalRole) or something.
So we have to add it manually as:

topic.addToResourcePolicy(
	new iam.PolicyStatement({
		sid: "AWSCodeStarNotifications_publish",
		effect: iam.Effect.ALLOW,
		principals: [
			new ServicePrincipal("codestar-notifications.amazonaws.com"),
		],
		actions: ["SNS:Publish"],
		resources: [
			`arn:aws:sns:us-east-1:${process.env.CDK_DEFAULT_ACCOUNT}:codestar-notifications-MyTopicForNotificationRules`
		],
		conditions: {
			"StringEquals": {
				"aws:SourceAccount": process.env.CDK_DEFAULT_ACCOUNT
			}
		}
	})
);

@federicobarera
Copy link

@samlaf I must have my wires crossed. Confirm it works after including buildPipeline between the pipeline and the notification

@TomaszSzusterTR
Copy link

@federicobarera.

Thank you mate.
It worked after invoking

pipeline.buildPipeline()

@qinjie
Copy link

qinjie commented Feb 8, 2022

I need to add resource policy mentioned by @samlaf's before i can deploy the template. But for an existing SNS topic, the addToResourcePolicy() doesn't modify its access policy.

    const targetTopic = sns.Topic.fromTopicArn(
      this,
      "sns-notification-topic",
      topicArn
    );
    targetTopic.addToResourcePolicy(
      new iam.PolicyStatement({
        sid: "AWSCodeStarNotifications_publish",
        effect: iam.Effect.ALLOW,
        principals: [
          new iam.ServicePrincipal("codestar-notifications.amazonaws.com"),
        ],
        actions: ["SNS:Publish"],
        resources: ["*"],
      })
    );

@Sumanthshetty23
Copy link

I am trying it out in python.
I did add pipeline.buildPipeline() before my rule.
and after my pipeline.

pipeline = CodePipeline(
            self,
            id,
            pipeline_name=id,
            synth=synth_step,
            cross_account_keys=True,
            code_build_defaults=pipelines.CodeBuildOptions(
                build_environment=BuildEnvironment(
                    build_image=aws_codebuild.LinuxBuildImage.STANDARD_5_0,
                    privileged=True,
                )
            ),
        )

but i am getting.

" pipeline.buildPipeline()
AttributeError: 'CodePipeline' object has no attribute 'buildPipeline'
"

is there any work around? or is there something i missed?

@atali
Copy link

atali commented Jan 27, 2023

@Sumanthshetty23 in python the function should be called as below :

pipeline.build_pipeline()

@TheRealAmazonKendra TheRealAmazonKendra added effort/medium Medium work item – several days of effort and removed effort/small Small work item – less than a day of effort in-progress This issue is being actively worked on. labels Jan 28, 2023
@acatala-sistrol
Copy link

@Sumanthshetty23, maybe you're using @aws-cdk/code_pipelines instead @aws-cdk/pipelines module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/pipelines CDK Pipelines library effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2
Projects
None yet
Development

Successfully merging a pull request may close this issue.