creating aws IAM Role using cloudformation does not create RolePolicies - amazon-web-services

I'm creating an ec2 instance with a role that provides access to kinesis streams and Dynamodb offset Tables. I am using aws cloudformation for that.
Problem I'm having is while creating the Streaming Access IAM Role itself.
So, I will have following structure,
has
StreamingAccessRole ----------> RolePolicy1(kinesis:*), RolePolicy2(dynamodb:*)
The template to create the AWS IAM role with two policies, one for kinesis and the other for dynamodb :
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"teamIdentifier": {
"Type": "String",
"Default": "a28",
"Description": "Identifier for the team"
}
},
"Resources": {
"StreamingAccessRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/a28/",
"Policies": [
{
"PolicyName": "Stream-ConsumerOffset-RW-AccessPolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "kinesis:*",
"Resource": "arn:aws:kinesis:us-west-2:*:stream/a28-*"
},
{
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": "arn:aws:dynamodb:us-west-2:*:table/a28-*"
}
]
}
}
]
}
}
}
}
It creates the Access Role but without role-policies.
$ aws iam get-role --role-name a28-streaming-access-role-st-StreamingAccessRole-14QHMTIOIRN5X --region us-west-2 --profile aws-federated
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
},
"RoleId": "AROAIFD6X2CJXTKLVQNLE",
"CreateDate": "2017-04-07T18:54:59Z",
"RoleName": "a28-streaming-access-role-st-StreamingAccessRole-14QHMTIOIRN5X",
"Path": "/a28/",
"Arn": "arn:aws:iam::500238854089:role/a28/a28-streaming-access-role-st-StreamingAccessRole-14QHMTIOIRN5X"
}
}
Listing the role-policies
$ aws iam list-role-policies --role-name a28-streaming-access-role-st-StreamingAccessRole-14QHMTIOIRN5X --region us-west-2 --profile aws-federated
{
"PolicyNames": []
}
which means it did not even create any policies,
aws iam list-policies --region us-west-2 --profile aws-federated | grep Stream-ConsumerOffset-RW-AccessPolicy
But if I supplied only kinesis:* statement in above example, it creates a policy, but not with dynamodb:* alone.
So, my question is how am supposed to provide multiple RolePolicies using one cloudformation AWS::IAM::Role template, or is this specific to dynamodb?

There's an intermittent race condition when you create the Policy in the Role. Create the Policy separately with AWS::IAM::Policy and set the Roles property to the Role. The problem will go away.

Your template worked perfectly fine for me.
I ran your template and then:
$ aws iam get-role --role-name stack1-StreamingAccessRole-1KDUTVG1OLLQM
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
},
"RoleId": "AROAJADV75HTIM6C62YXQ",
"CreateDate": "2017-04-08T22:22:21Z",
"RoleName": "stack1-StreamingAccessRole-1KDUTVG1OLLQM",
"Path": "/a28/",
"Arn": "arn:aws:iam::123456789012:role/a28/stack1-StreamingAccessRole-1KDUTVG1OLLQM"
}
}
Listing the role-policies:
$ aws iam list-role-policies --role-name stack1-StreamingAccessRole-1KDUTVG1OLLQM
{
"PolicyNames": [
"Stream-ConsumerOffset-RW-AccessPolicy"
]
}
The policy is attached as an inline policy, so it will not appear in list-policies. Rather, use get-role-policy to view it:
$ aws iam get-role-policy --role-name stack1-StreamingAccessRole-1KDUTVG1OLLQM --policy-name Stream-ConsumerOffset-RW-AccessPolicy
{
"RoleName": "stack1-StreamingAccessRole-1KDUTVG1OLLQM",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "kinesis:*",
"Resource": "arn:aws:kinesis:us-west-2:*:stream/a28-*",
"Effect": "Allow"
},
{
"Action": "dynamodb:*",
"Resource": "arn:aws:dynamodb:us-west-2:*:table/a28-*",
"Effect": "Allow"
}
]
},
"PolicyName": "Stream-ConsumerOffset-RW-AccessPolicy"
}

The reason could be race condition as already answered in this answer by Tim Bassett, I simply wanted to add final solution that worked, and how to add AWS::IAM::Policy to cloudformation.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Some Streaming api devops",
"Parameters": {
"environment": {
"Type": "String",
"Default": "staging",
"Description": "environment"
}
},
"Resources": {
"StreamingAccessRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "StreamingAccessRole",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/a28/"
}
},
"StreamConsumerOffsetRWAccessPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": "kinesis:*",
"Resource": "arn:aws:kinesis:us-west-2:051620159240:stream/a28-*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem",
"dynamodb:CreateTable",
"dynamodb:DeleteItem",
"dynamodb:DeleteTable",
"dynamodb:DescribeLimits",
"dynamodb:DescribeReservedCapacity",
"dynamodb:DescribeReservedCapacityOfferings",
"dynamodb:DescribeStream",
"dynamodb:DescribeTable",
"dynamodb:GetItem",
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:ListStreams",
"dynamodb:ListTables",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:UpdateItem",
"dynamodb:UpdateTable"
],
"Resource": "arn:aws:dynamodb:us-west-2:051620159240:table/a28-*"
},
{
"Action": [
"sns:*Permission",
"sns:Create*",
"sns:Delete*",
"sns:Publish",
"sns:ReceiveMessage",
"sns:Set*"
],
"Resource": [
"arn:aws:sns:us-west-2:051620159240:a28-*"
],
"Effect": "Allow"
}
]
},
"PolicyName": "StreamConsumerOffsetRWAccessPolicy",
"Roles": [
{
"Ref": "StreamingAccessRole"
}
]
}
}
}
}

Related

User: ARN is not authorized to perform: SNS:Publish on resource: ARN (AWS Integration error)

I am trying to monitor an AWS Cloud environment using AquaSec. AquaSec helps you connect with your AWS environment by providing a CloudFormation template, which you would deploy at your AWS environment. Once it is deployed, you use it's ARN in AquaSec to connect/integrate both. Any alert in Aquasec would be sent to an SNS Topic which would send it further to a HTTPS endpoint.
This is the CloudFormation template file,
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Aqua CSPM security scanner cross-account role",
"Parameters": {
"ExternalId": {
"Type": "String",
"Description": "The external ID auto-generated from the Aqua Cloud dashboard. Do not change this value.",
"AllowedPattern": "[-a-z0-9]*",
"ConstraintDescription": "Must be lowercase or numbers, no spaces, dashes ok."
}
},
"Resources": {
"AquaCSPMRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::057012691312:role/lambda-cloudsploit-api"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": {
"Ref": "ExternalId"
}
},
"IpAddress": {
"aws:SourceIp": "3.231.74.65/32"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::057012691312:role/lambda-cloudsploit-collector"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": {
"Ref": "ExternalId"
}
},
"IpAddress": {
"aws:SourceIp": "3.231.74.65/32"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::057012691312:role/lambda-cloudsploit-remediator"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": {
"Ref": "ExternalId"
}
},
"IpAddress": {
"aws:SourceIp": "3.231.74.65/32"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::057012691312:role/lambda-cloudsploit-tasks"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": {
"Ref": "ExternalId"
}
},
"IpAddress": {
"aws:SourceIp": "3.231.74.65/32"
}
}
}
]
},
"Policies": [
{
"PolicyName": "aqua-cspm-supplemental-policy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:DescribeActiveReceiptRuleSet",
"athena:GetWorkGroup",
"logs:DescribeLogGroups",
"logs:DescribeMetricFilters",
"elastictranscoder:ListPipelines",
"elasticfilesystem:DescribeFileSystems",
"servicequotas:ListServiceQuotas",
"ssm:ListAssociations",
"dlm:GetLifecyclePolicies",
"airflow:ListEnvironments",
"glue:GetSecurityConfigurations",
"devops-guru:ListNotificationChannels"
],
"Resource": "*"
}
]
}
}
],
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/SecurityAudit"
]
}
}
},
"Outputs": {
"AquaCSPMeArn": {
"Description": "The role ARN of the cross-account user. Copy this into Aqua Cloud.",
"Value": {
"Fn::GetAtt": [
"AquaCSPMRole",
"Arn"
]
}
},
"StackVersion": {
"Description": "The Aqua CSPM stack version.",
"Value": "2.0"
}
}
}
I am trying to setup an Amazon SNS Topic, use its ARN here at Aquasec to send out alerts. Once i create an SNS topic, and copy it's ARN at Aquasec, and try out a test notification - I keep getting the error,
{
"message": "User: arn:aws:sts::057012691312:assumed-role/lambda-cloudsploit-api/cloudsploit-api is not authorized to perform: SNS:Publish on resource: arn:aws:sns:us-east-1:940386435759:Sample_Aqua_Integration",
"code": "AuthorizationError",
"time": "2021-04-19T22:15:54.463Z",
"requestId": "bc808944-3430-5683-aed1-d1bc376a70f5",
"statusCode": 403,
"retryable": false,
"retryDelay": 50.2772842473471
}
I have tried nearly every possible way - changed topic policy(various combinations of "Principle" field) in the SNS Topic, tried to give permissions in the specific IAM role. Nothing seems to work and I get the same error.
I feel it has to do something with the template file (in the 'assumeRole' configuration) ?
Any suggestions on how and what to change/try?
Thanks

Cross-Account ECS Deployment

I am trying to deploy an image from ECR of one account (AccountA) to ECS Cluster of another (AccountB) using CodePipeline. I am getting a permissions related error in the deploy phase.
Here is my pipeline role in AccountA:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketVersioning"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::<bucketname>/*"
],
"Effect": "Allow"
},
{
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": [
"*"
],
"Effect": "Allow"
},
{
"Action": [
"codebuild:BatchGetBuilds",
"codebuild:InvalidateProjectCache",
"codebuild:StartBuild",
"codebuild:StopBuild",
"codebuild:UpdateProject",
"codebuild:UpdateWebhook"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"sts:AssumeRole"
],
"Resource": "arn:aws:iam::<AccountB>:role/taskexecutionrole",
"Effect": "Allow"
}
]
}
The arn:aws:iam::<AccountB>:role/taskexecutionrole role exists in AccountB and trusts AccountA. Here is the role in AccountB:
{
"Effect": "Allow",
"Action": "ecs:*",
"Resource": [
"*"
]
}
The pipeline has a ECR source, build stage generates an imagedefinitions.json file. And finally the deployment stage does ECS deploy.
The error I am getting is:
Invalid action configuration
Identifier is for AccountB. Your accountId is AccountA
This answer helps only for manual CLI deployment and I have tried the solution from this answer.
Any pointers what I'm missing?
Lets assume:
Account_A => CodePipeline & Source
Account_B => ECS
Here is what is required:
Account_A:
* AWSCodePipelineServiceRole
* Artifact_Store_S3_Bucket
* KMS_Key_for_Pipeline_Artifact (Customer Managed Key)
* Bucket Policy on Artifact_Store_S3_Bucket to Allow Account_B access
* Key Policy on KMS_Key_for_Pipeline_Artifact to Allow Access to Cross_Account_Role (from Account_B)
Account_B
* Cross_Account_Role (Trust relationship with Account_A and Full_ECS permissions)
* ECS with a running that is to be replaced with deployment
imagedefinitions.json (must be part of your source code)
[
{
"name": "container_name",
"imageUri": "nginx:latest"
}
]
Bucket_Policy on Artifact_Store_S3_Bucket
{
"Version": "2012-10-17",
"Id": "SSEAndSSLPolicy",
"Statement": [
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
},
{
"Sid": "DenyInsecureConnections",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account_B:root"
},
"Action": [
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account_B:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket"
}
]
}
pipeline.json:
{
"pipeline": {
"name": "test",
"roleArn": "arn:aws:iam::Account_A:role/service-role/AWSCodePipelineServiceRole",
"artifactStore": {
"type": "S3",
"location": "Artifact_Store_S3_Bucket",
"encryptionKey": {
"id": "arn:aws:kms:us-east-1:Account_A:key/KMS_Key_for_Pipeline_Artifact",
"type": "KMS"
}
},
"stages": [
{
"name": "Source",
"actions": [
{
"name": "Source",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"provider": "CodeCommit",
"version": "1"
},
"runOrder": 1,
"configuration": {
"BranchName": "master",
"PollForSourceChanges": "false",
"RepositoryName": "code"
},
"outputArtifacts": [
{
"name": "SourceArtifact"
}
],
"inputArtifacts": [],
"region": "us-east-1"
}
]
},
{
"name": "Deploy",
"actions": [
{
"name": "Deploy",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"provider": "ECS",
"version": "1"
},
"runOrder": 1,
"roleArn": "arn:aws:iam::Account_B:role/CrossAccount_Role",
"configuration": {
"ClusterName": "<Cluster>",
"ServiceName": "<Service>"
},
"outputArtifacts": [],
"inputArtifacts": [
{
"name": "SourceArtifact"
}
],
"region": "us-east-1"
}
]
}
],
"version": 1
}
}
To Update the Pipeline:
$ aws codepipeline update-pipeline --region us-east-1 --cli-input-json file://pipeline.json

Planning to create a CFT which need 3 roles with managed policy and a inline policy attached to them

I am trying to create an CFT which has
1. 3 different roles with Managed policy
2. INline policy which should be added to three roles which are created in CFT.
But i could not do as this is throwing me error saying atleast one resource must be defined.
Please help me in achieving this.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"EMRDefaultRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "EMR_DefaultRole",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "elasticmapreduce.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceRole"
]
}
},
"EMREC2DefaultRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "EMR_EC2_DefaultRole",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforEC2Role"
]
}
},
"EMRAutoScalingDefaultRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "EMR_AutoScaling_DefaultRole",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": [ "elasticmapreduce.amazonaws.com",
"application-autoscaling.amazonaws.com"]
},
"Action": "sts:AssumeRole"
}]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforAutoScalingRole"
]
}
},
"EMRS3Policies": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "Moodys-IAM-EMR-S3-Access-Policy",
"PolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:HeadBucket",
"s3:GetObject"
],
"Resource": {
"Fn::Join": ["", ["arn:aws:s3:::mit-", {
"Ref": "AWS::AccountId"
}, "-emr-files/*"]]
}
}
]
},
"Roles": [{
"Ref": "EMRDefaultRole"},
{"Ref": "EMREC2DefaultRole"},
{"Ref": "EMRAutoScalingDefaultRole"
}]
}
}
}
}
Like i am expecting three Role where an managed policy and inline policy are attached.
You are missing resource attribute in your role statements.
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": [ "elasticmapreduce.amazonaws.com",
"application-autoscaling.amazonaws.com"]
},
"Action": "sts:AssumeRole"
}]
This should be (it holds for all of the statements)
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": [ "elasticmapreduce.amazonaws.com",
"application-autoscaling.amazonaws.com"]
},
"Action": "sts:AssumeRole",
"Resource": [
"arn-of-your-resource-or-wildcard"
]
}]

Is this the correct way to write a CFT for lambda to be triggered by SQS?

Hello I recently made a CFT for my lambda and sqs (both on the same account/region) but I noticed that when I go to the aws console, it shows the SQS resource both on the "input side" and the "output side" of my lambda. Is this intentional? or did I just do my CFTs incorrectly. Below is the relevant JSON code.
"MyLambdaFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
],
"Resource": {
"Fn::Sub": "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:test-${Environment}-my-queue"
}
}
]
}
}
]
}
},
"OutputRouterEventSource": {
"Type": "AWS::Lambda::EventSourceMapping",
"Properties": {
"BatchSize": 10,
"Enabled" : true,
"EventSourceArn": {
"Fn::Sub": "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:test-${Environment}-my-queue"
},
"FunctionName": {
"Fn::GetAtt": [
"MyLambdaFunction",
"Arn"
]
}
}
},
"OutputRouterLambdaInvokePermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"Principal": "sns.amazonaws.com",
"SourceArn": {
"Fn::Sub": "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:test-${Environment}-my-queue"
},
"FunctionName": {
"Fn::Sub": "test-${Environment}-my-lambda"
}
}
}
It is normal to have SQS on both side in this case: SQS triggers your Lambda function (left side) and your Lambda function's role must have the permission to receive and delete messages from the queue (right side).
(I think your are mixing services in your OutputRouterLambdaInvokePermission resource where the principal is SNS and the source references the arn of a SQS queue, you can drop this resource as it is not needed for SQS triggers)

Attach policy to a IAM Role

Following cloudformation template gives error on line 9 :
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Policy to allow send receive message from SQS Queue",
"Resources" : {
"MyPolicy" : {
"Type" : "AWS::IAM::Policy",
"Properties" : {
"PolicyName" : "CFUsers",
"Roles": [ { "arn:aws:iam::710161973367:role/Cognito_CFIAuth_Role" } ],
"PolicyDocument" : {
"Version" : "2012-10-17",
"Statement": [
{
"Sid": "Sid1482400105445",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::710161973367:role/Cognito_CFIAuth_Role"
},
"Action": [
"SQS:SendMessage",
"SQS:ReceiveMessage",
"SQS:DeleteMessage",
"SQS:GetQueueUrl"
],
"Resource": "arn:aws:sqs:ap-south-1:710161973367:CFI-Trace"
}
]
}
}
}
}
I want role Cognito_CFIAuth_Role to have message send/read/delete previleges on SQS queue CFI-Trace. How do I attach SQS operation privileges to IAM Role ?
First, Line 9 contains a JSON syntax error, the brackets {} around your Role string should be removed:
"Roles": [ "arn:aws:iam::710161973367:role/Cognito_CFIAuth_Role" ],
Second, AWS::IAM::Policy's Roles property accepts "The names of AWS::IAM::Roles to attach to this policy", not full ARNs, so your line should be:
"Roles": [ "Cognito_CFIAuth_Role" ],
You also need a missing closing bracket } at the end of your example.
With the AWS::IAM::Policy resource, you're creating an inline policy. http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html explains that this takes a list of "The names of AWS::IAM::Roles, which I take to be the logical name of role resources defined within the same stack.
If you want to attach the policy to a preexisting role, you should use the ManagedPolicy type instead. http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html#cfn-iam-managedpolicy-roles takes the name of the preexisting role(s).
Cloudformation type IAM::Policy is for Users and Groups. Roles and instance profiles are for ec2. You have conflated both ideas. If you have the role predefined in a different CFN then you use just an Instance Profile for your EC2 instance, if not you can create it too and then ref it
"RootInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ {
"arn:aws:iam::710161973367:role/Cognito_CFIAuth_Role"
} ]
}
}
or
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"SQSRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"SQS:SendMessage",
"SQS:ReceiveMessage",
"SQS:DeleteMessage",
"SQS:GetQueueUrl"
],
"Resource": "arn:aws:sqs:ap-south-1:710161973367:CFI-Trace"
}
]
}
}
]
}
},
"RootInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [
{
"Ref": "SQSRole"
}
]
}
}
}
}
IAM Policy
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html
IAM role
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
Now there is also SQS Policy
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-policy.html
You can also attach ManagedPolicyArns to CloudFormation resource type AWS::IAM::Role https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html#cfn-iam-role-managepolicyarns