Search code examples
amazon-cloudwatchamazon-snsaws-cdk

cross account SNS topic publish


I have an SNS topic in account A that takes an error and sends to pager duty

I have another account - Account B that has several services in it, fargate, SQS etc but I have several cloudwatch alarms / actions setup to publish alerts to this SNS topic in account A

I get this error on Account B (the one trying to access the cross account service)

Failed to execute action arn:aws:ACCOUNT-A:sns-topic. Received error: "Resource: arn:aws:cloudwatch:ACCOUNT-B is not authorized to perform: SNS:Publish on resource: ACCOUNT-A:sns"

here is my AWS CDK code for Account A

const accountATopic= new sns.Topic(this, 'accountATopic', {
   displayName: 'accountATopic'
 });
 accountATopic.addSubscription(new snsSubscriptions.UrlSubscription('Externalurl'));
 
 accountATopic.grantPublish(new iam.AccountPrincipal('ACCOUNTB'));

and then in ACCOUNT B (not showing the alarms)

 const ACCOUNTBTopic = sns.Topic.fromTopicArn(this, 'ACCOUNTBTopic ', 'ACCOUNT-A-ARN');
      const action = new cloudwatchActions.SnsAction(ACCOUNTBTopic );



      ACCOUNTBTopic .addToResourcePolicy(new PolicyStatement({
        resources: ['ACCOUNT-A-ARN'],
        actions: ['SNS:Publish'],
        effect: Effect.ALLOW,
        }))


Solution

  • For anyone that comes across this in the future - here is what I did to get it working:

        const accountATopic= new sns.Topic(this, 'accountATopic', {
       displayName: 'accountATopic'
     });
     accountATopic.addSubscription(new snsSubscriptions.UrlSubscription('Externalurl'));
     
      let snsPolicy = new PolicyStatement({effect:Effect.ALLOW,
          resources:[accountATopic.topicArn],
          actions:["SNS:Publish"],
          principals:[
          new AccountPrincipal('ACCOUNTB_ID'),
         ]
        })
          //or optionally:
        //snsPolicy.addAnyPrincipal()
    
    
          accountATopic.addToResourcePolicy(snsPolicy)
    

    The grant publish method does not seem to allow it to work, also according to AWS documentation on cross account SNS / CloudWatch they suggested adding the org id for a condition - this did not work for me and had to remove it