问题
I have 2 services with different Cloudformation YAML templates and want to add another policy to a queue policy defined in producer service (to allow consumer to receive and delete messages). However, my current solution simply overrides the existing policy instead of appending it (i. e., only consumer service role remains in the policy).
This is Cloudformation template SQS part for producer:
ProducerQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Id: SQSPolicy
Statement:
- Effect: Allow
Principal:
AWS:
- !GetAtt ServiceRole.Arn
Resource: !GetAtt ProducerQueue.Arn
Action:
- 'sqs:DeleteMessage'
- 'sqs:ReceiveMessage'
- 'sqs:ListQueues'
- 'sqs:SendMessage'
- 'sqs:GetQueueUrl'
- 'sqs:GetQueueAttributes'
Queues: [ !Ref ProducerQueue ]
ProducerDeadLetterQueue:
Type: 'AWS::SQS::Queue'
Properties:
QueueName: !Sub "${AWS::StackName}-ProducerDLQ.fifo"
FifoQueue: true
ContentBasedDeduplication: false
ProducerQueue:
Type: 'AWS::SQS::Queue'
Properties:
QueueName: !Sub "${AWS::StackName}-ProducerQueue.fifo"
FifoQueue: true
MessageRetentionPeriod: 1209600
ContentBasedDeduplication: false
RedrivePolicy:
deadLetterTargetArn: !GetAtt ProducerDeadLetterQueue.Arn
maxReceiveCount: 9
# Outputs -------------------------------------------------------------------------
Outputs:
ProducerQueueUrl:
Value: !Ref ProducerQueue
Export:
Name: ProducerQueueUrl
ProducerQueueArn:
Value: !GetAtt ProducerQueue.Arn
Export:
Name: ProducerQueueArn
And this is Cloudformation for consumer:
#SQS policy configuration for consumer
ProducerQueueConsumptionPolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Id: SQSConsumptionPolicy
Statement:
- Effect: Allow
Principal:
AWS:
- !GetAtt ServiceRole.Arn
Resource:
Fn::ImportValue: ProducerQueueArn
Action:
- 'sqs:DeleteMessage'
- 'sqs:ReceiveMessage'
- 'sqs:GetQueueUrl'
- 'sqs:GetQueueAttributes'
Queues:
- Fn::ImportValue: ProducerQueueUrl
What needs to be done to change this behavior?
回答1:
If you just want to merge the queue policies, write a cloudformation macro that reads a policy definition from the template and merges it with the existing queue policy. The macro gets given a json version of the template and you can manipulate it how you like in a lambda so you can check for an existing queue policy and update the template appropriately.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-macros.html
An alternative approach is just weaken the queue policy so that most operations are allowed by anything in the account. Then add permissions to whatever is reading and writing to the queue (eg lambdas) through separate roles. So the lambda doing the reading would use one role that allowed reading and the lambda doing the writing would use a different role that allowed writing.
Obviously that might not fit in with how you've arranged you're security so might not be suitable.
来源:https://stackoverflow.com/questions/58379911/how-to-add-a-new-statement-to-an-existing-sqs-queuepolicy-from-another-template