Send message from lambda account A to an SQS of account B - amazon-web-services

I need to send message from lambda account A to an SQS of another account B.
In account B, I have created the sqs like this:
Resources:
SampleSqs:
Type: "AWS::SQS::Queue"
Properties:
QueueName: sample-sqs-service-queue.fifo
FifoQueue: true
VisibilityTimeout: 400
ContentBasedDeduplication: true
and created the access role policy as:
SqsRole:
Type: AWS::IAM::Role
Properties:
RoleName: sample-sqs-Account-Role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS:
- arn:aws:iam::<Account-A>:root
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSQSFullAccess
I also tried adding the sqs queue as resource under statement section, but is failing at the time of deployment with the below message:
SqsRole - Has prohibited field Resource (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument;
In account A, I am trying to acces the account B sqs SampleSqs, by importing the queue url,but i am getting access denied, code for account A:
iamRoleStatements:
- Effect: Allow
Action:
- sts:AssumeRole
Resource:
- arn:aws:iam::$<AccountB>:role/sample-sqs-Account-Role
trying to access that sqs through its url in my code but getting access denied.
I am quite new to aws and serverless framework, Could someone please help me with what serverless code setup I require in both interface's to give Account B sqs queue's access to account A.
I tried adding the sqs queue as resource under statement section in sqsRole, but is failing at the time of deployment with the below message:
SqsRole - Has prohibited field Resource (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument;

Have you checked Amazon documentation on error: https://aws.amazon.com/premiumsupport/knowledge-center/iam-principal-policy/
More importantly, I do not know your exact scenario here but I would think instead of creating a whole role in account be to be assumed to access sqs, it would be easier and probably more appropriate to simply grant necessary permissions by changing the policy on sqs (resource policy).
There are very easy to understand examples directly addressing this use-case here: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-examples-of-sqs-policies.html

Related

How to use AWS CloudFormation pseudoparameter inside IAM Policy Document

I am using AWS CloudFormation (YAML-based) to deploy an IAM role. This role should both be allowed to deploy other CloudFormation resources and to have the root of the AWS account it gets deployed into as a trusted entity.
I am trying to supply the account-id using the built-in pseudo-parameter AWS::AccountId:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html#cfn-pseudo-param-accountid .
Here is what I have tried, following the official doc: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html (just showing the resources section of my CFN template):
Resources:
IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: ["sts:AssumeRole"]
Effect: Allow
Principal:
Service: [cloudformation.amazonaws.com]
AWS: arn:aws:iam::AWS::AccountId:root # <-- ERROR HERE !
Which causes a MalformedPolicyDocument error due to an Invalid principal in the CloudFormation stack (in the AWS Management Console, under Events):
Invalid principal in policy: "AWS":"arn:aws:iam::AWS::AccountId:root" (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument
I have tried varying the syntax for the AWS Principal's value:
with and without quotation marks
with and without square brackets
Where is the error in the Principal, and how can it be corrected ?
We need to use Intrinsic functions !Sub for variables like AWS::Region, AWS::AccountId, AWS::StackName, etc
AWS: !Sub arn:aws:iam::${AWS::AccountId}:root

CloudFormation Role using QueuePolicy Ref as a ManagedPolicy in IAM Role Resource?

I am trying to make an IAM Role via CloudFormation and am getting this error when trying to attach a QueuePolicy resource to an IAM::Role resource.
ARN stack-personSQSPolicy-3F02ILJ96DB1 is not valid. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: InvalidInput; Request ID: 4410ba76-30ce-4d15-be3c-6d5040f971f0)
Here is my CloudFormation Role and Policy definition:
APIGatewaySQSRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: 'sts:AssumeRole'
Effect: Allow
Principal:
Service: apigateway.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- !Ref personSQSPolicy
- 'arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs'
personSQSPolicy:
Type: 'AWS::SQS::QueuePolicy'
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
Effect: Allow
Action: 'sqs:SendMessage'
Resource: !GetAtt personSQS.Arn
Queues:
- !Ref personSQS
What's the point of Type: 'AWS::SQS::QueuePolicy' If it doesn't allow the use as an Arn in the Role resource? It seems like I still have to manually create that policy in the IAM Role resource block.
Policies:
- PolicyDocument:
Statement:
- Action: sqs:SendMessage
Effect: Allow
Resource: !GetAtt 'personSQS.Arn'
PolicyName: apig-sqs-send-msg-policy
Is there a way to avoid this?
Since SQS Queues can be publicly accessible, they need a mechanism for security if people are going to access it without a role.
This is why you have a QueuePolicy AWS::SQS::QueuePolicy that you can define for the queue and it can be applied to one or more queues. It will help you define who's allowed to access it, how etc directly from the point of view of the queue.
You then attach your QueuePolicy to your Queue(s) with the Cloudformation attribute Queues (see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-policy.html#cfn-sqs-queuepolicy-queues)
If you want to define a role for accessing your queue, yes you'll have to describe kind of the same policy but this time from the point of view of the resource accessing it but I still recommend that you secure the access to your queue with a Queue Policy.
As for your last question, defining the QueuePolicy and attaching it to your queue is the right way to do it.
Watch out, the Queues attribute expect a list of Queue URLs, not ARNs.

Amazon Forecast's create_dataset_import_job S3 Role Requires Star-Access to S3-Resources

I've written a Lambda function that creates a dataset import job (link to API). The Datasource property of that request requires an S3 Config item, which in turn, contains an IAM Role "that Amazon Forecast can assume to access the Amazon S3 bucket or files".
In trying to follow the principle of least access, I'd like to give that role (Cloud Formation definition below) the fewest privileges possible. I'm able to restrict its actions to only List and Get; however, it doesn't work unless I give it access to Resource: *. I'd prefer to give it access to Resource: arn:aws:s3:::my-bucket/* (or better yet Resource: arn:aws:s3:::my-bucket/path/to/my_file.csv. The error message I get (when not using Resource: *) is
An error occurred (404) when calling the HeadObject operation: Not Found
or
An error occurred (403) when calling the HeadObject operation: Forbidden
depending on whether I'm running local (via SAM CLI) or in the LAMBDA console.
¿Has anyone come across a reason why Forecast would error-out when creating a dataset import job without write only access to ALL of s3, as opposed to just one bucket, or better one file?
CreateDatasetImportJobS3Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- forecast.amazonaws.com
Action: sts:AssumeRole
Policies:
-
PolicyName: ReadFromBucketPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Action:
- s3:ListBucket
- s3:GetObject
# I'd like to be able to do this without a STAR resource;
# however, it doesn't seem to work without
Resource: "*"
s3://my-bucket/* is not the correct format. The correct format must be a valid ARN, such as arn:aws:s3:::my-bucket/*. Furthermore, when you have API actions like ListBucket, you need to list the bucket ARN not a label within that bucket. So you should really have the Resource specified as arn:aws:s3:::my-bucket.
To be safe, I would usually put both, making your final policy:
Resource:
- "arn:aws:s3:::my-bucket"
- "arn:aws:s3:::my-bucket/*"
The first resource, arn:aws:s3:::my-bucket, covers operations such as ListBucket. The second resource, arn:aws:s3:::my-bucket/*, covers operations such as GetObject (since the object itself would be under a path covered by the wildcard).

Creating Role for EC2 Service in Cloudformation

I am trying to create a full access role (using an AWS Managed Policy) to all EC2 instances to call AWS services via Cloudformation in YAML.
This is my code:
AWSTemplateFormatVersion: 2010-09-09
Description: Ansible Role
Resources:
AnsibleRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: 'Allow'
Action: 'ec2:*'
Principal:
Service: 'ec2.awsamazon.com'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonEC2FullAccess'
RoleName: 'EC2-FullAccess'
DeletionPolicy: Delete
I get the following error:
Invalid principal in policy: "SERVICE":"ec2.awsamazon.com"
(Service: AmazonIdentityManagement; Status Code: 400; Error
Code: MalformedPolicyDocument; Request ID: e43214f8-b6f9-11e9-9891-4dc84fd279dd)
I am perplexed as to why it doesn't recognize the service. Additionally, if I change Action: 'ec2:*' to Action: 'sts.AssumeRole' I get another error.
Any assistance is greatly appreciated.
There are multiple issues with your template:
The service identifier is malformed. It should be 'ec2.amazonaws.com'.
The action must be 'sts:AssumeRole'. This is the only action which is valid inside an IAM trust policy.
The DeletionPolicy is not necessary because it is the default for this resource.
Set the RoleName only if really necessary because IAM names are global on a per-account basis and you cannot execute multiple stacks when using this attribute.
For more information see the AWS CloudFormation template examples.
You use the correct managed policy ARN if you want to grant your new role permission to call all kinds of ec2 actions. If you want to restrict your Ansible role further, take a look at the example policies for EC2 in the docs [1][2]. They are much more restrictive (and thus secure) than the managed full access policy AmazonEC2FullAccess. Maybe also the other managed policies such as AmazonEC2ReadOnlyAccess [3] are feasible?
References
[1] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html
[2] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-policies-for-amazon-ec2.html
[3] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UsingIAM.html#intro-to-iam

User is not authorized to perform: SNS:CreateTopic on resource

I wanted to monitor certain parameters (TotalErrorRate and Latency) with CloudWatch and I wanted a "Simple Notification Service" (SNS) to send me an email, when an (cloudWatch) alarm is thrown:
EscalationTopic:
Type: "AWS::SNS::Topic"
Properties:
DisplayName: My Monitoring
Subscription:
- Endpoint: !Ref EmailForNotification
Protocol: email
EscalationTopicEmailSubscriber:
Type: "AWS::SNS::Subscription"
Properties:
Endpoint: !Ref EmailForNotification
Protocol: email
TopicArn: !Ref EscalationTopic
But I get this error:
User is not authorized to perform: SNS:CreateTopic on resource(Service: AmazonSNS; Status Code: 403; Error Code: AuthorizationError (see screenshot)
What I did to solve it, is creating a topicPolicy:
SNSTopicPolicy:
Type: 'AWS::SNS::TopicPolicy'
Properties:
Topics:
- !Ref EscalationTopic
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: 'sns:CreateTopic'
Resource: !Ref EscalationTopic
Principal:
AWS: '*'
But the problem still persists.
EDIT:
In the SNS console, I could manually create a new topic. Shouldn't it mean that I got the permission in order to createTopic?
I had a similar issue with Amazon SES. Apparently my "AmazonSESFullAccess" permission wasn't enough and I solved it by adding the "AmazonSNSFullAccess" permission to my IAM user at https://console.aws.amazon.com/iam/home#/users/MY_IAM_USER_NAME_GOES_HERE
The error message states the problem quite accurately. The credentials used to create the CloudFormation stack (presumably your login credentials unless you specified a Role during stack creation) is not authorized to create an Amazon SNS topic.
You should look at the permissions associated with your IAM User and add the necessary permissions.
Adding an SNS Topic Policy will have no impact because it is used to give SNS a set of permissions, whereas you need permissions to create the Topic itself.