KodeKloud Engineer | 100 Days of Cloud (AWS) | Day 47: Integrating AWS SQS and SNS for Reliable Messaging

Hello Fellow Learners,

I’ve been trying to solve this issue for quite a while. Hope this topic will help me to move forward with my learning.

In the task (Day 47 of AWS Cloud) it’s required to create a cloudformation stack /root/datacenter-priority-stack.yml, the stack name must be datacenter-priority-stack and it should create the following resources:

  1. Two SQS queues named datacenter-High-Priority-Queue and datacenter-Low-Priority-Queue.
  2. An SNS topic named datacenter-Priority-Queues-Topic.
  3. A Lambda function named datacenter-priorities-queue-function that will consume messages from the SQS queues. The Lambda function code is provided in /root/index.py on the AWS client host.
  4. An IAM role named lambda_execution_role that provides the necessary permissions for the Lambda function to interact with SQS and SNS.

I’ve created the following yaml file.

AWSTemplateFormatVersion: 2010-09-09
Description: KodeKloud Stack
Resources:
  highPriorityQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: "datacenter-High-Priority-Queue"

  lowPriorityQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: "datacenter-Low-Priority-Queue"

  priorityQueuesTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: "datacenter-Priority-Queues-Topic"

  lambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: datacenter-priorities-queue-function
      Handler: index.lambda_handler
      Role: !GetAtt lambdaExecutionRole.Arn
      Runtime: python3.11
      Code:
        ZipFile: |
          import boto3
          import os
          sqs = boto3.client('sqs')
          def delete_message(queue_url, receipt_handle, message):
              response = sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=receipt_handle)
              return "Message " + "'" + message + "'" + " deleted"
              
          def poll_messages(queue_url):
              QueueUrl=queue_url
              response = sqs.receive_message(
                  QueueUrl=QueueUrl,
                  AttributeNames=[],
                  MaxNumberOfMessages=1,
                  MessageAttributeNames=['All'],
                  WaitTimeSeconds=3
              )
              if "Messages" in response:
                  receipt_handle=response['Messages'][0]['ReceiptHandle']
                  message = response['Messages'][0]['Body']
                  delete_response = delete_message(QueueUrl,receipt_handle,message)
                  return delete_response
              else:
                  return "No more messages to poll"
          def lambda_handler(event, context):
              response = poll_messages(os.environ['high_priority_queue'])
              if response == "No more messages to poll":
                  response = poll_messages(os.environ['low_priority_queue'])
              return response    

  SQSAndSNSManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: "SQSAndSNSAccess"
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - sqs:ReceiveMessage
              - sqs:GetQueueAttributes
            Resource: 
              - !GetAtt highPriorityQueue.Arn
              - !GetAtt lowPriorityQueue.Arn
          - Effect: Allow
            Action:
              - sns:Publish
            Resource: !Ref priorityQueuesTopic

  lambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: "lambda-execution-role"
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
              - lambda.amazonaws.com
        Version: 2012-10-17
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSQSFullAccess
      Path: /

The problem arises when I run aws cloudformation deploy --template-file datacenter-priority-stack.yml --stack-name datacenter-priority-stack --capabilities CAPABILITY_NAMED_IAM - the lab user has no required permissions

"User: arn:aws:iam::253882248345:user/kk_labs_user_715379 is not authorized to perform: iam:PassRole on resource: arn:aws:iam::253882248345:role/lambda-execution-role because no identity-based policy allows the iam:PassRole action

I would really appreciate any help that would move me any further and also any explanations on the matter.

Thank you all in advance!

Please refer to this solution and see if it helps.

Thank you so much! It worked!