How to reference AWS managed policy arn in cloudformation? - amazon-web-services

I am going to create an IAM user with cloudformation and need to attach an AWS managed policy AWSAppSyncInvokeFullAccess. I think I should use the managed policy like below code:
Resources:
publisherUser:
Type: AWS::IAM::User
Properties:
UserName: userName
ManagedPolicyArns:
- !Ref AWSAppSyncInvokeFullAccess
- !Ref AWSLambdaBasicExecutionRole
but it doesn't work since AWSAppSyncInvokeFullAccess is from AWS not from this template. What is the correct way to reference the policies?

These are existing AWS-managed policies. So you should use their full ARN, which you can get from IAM console:
Resources:
publisherUser:
Type: AWS::IAM::User
Properties:
UserName: userName
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSAppSyncInvokeFullAccess
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Update
Or to make it partition independent:
Resources:
publisherUser:
Type: AWS::IAM::User
Properties:
UserName: userName
ManagedPolicyArns:
- !Sub "arn:${AWS::Partition}:iam::aws:policy/AWSAppSyncInvokeFullAccess"
- !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"

Just in case anyone was wondering you can find the ARNs of all IAM policies by clicking on the name of the policy on the Policies page.

Related

aws lambda permission to IAM usergroup using cloudformation

I need create a way for execute especific lambdas for specific IAM users, then i am doing:
I am creating a Usergroup in cloudformation:
Resources:
XXXGroup:
Type: AWS::IAM::Group
And after I am creating a policy and add the policy to my UserGroup
UsersXPolicies:
Type: AWS::IAM::Policy
Properties:
Groups:
- !Ref XXXGroup
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "lambda:*"
Resource:
- !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:MyFunction
- !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:MyFunction2
PolicyName: xxx-access-policy
I try first only with "lambda:InvokeFunction" but it not works, then I try with lambda:* but it not works
After I am creating a user:
XXUser:
Type: AWS::IAM::User
Properties:
UserName: xxx.user
LoginProfile:
Password: l98GaTc9xzT9
PasswordResetRequired: true
Path: /
And finally i am adding the user to my usergroup:
USerAdditionX:
Type: AWS::IAM::UserToGroupAddition
Properties:
GroupName: !Ref XXXGroup
Users:
- !Ref XXUser
But after login with my new user i am getting the following error when i go to lambda service:
User: arn:aws:iam::xxxxxxxxx:user/xx.user is not authorized to perform: lambda:GetAccountSettings on resource: * because no identity-based policy allows the lambda:GetAccountSettings action
Access to specific lambdas from my new user
The problem is that lambda get its permission from a role.Policies are attached to role.
You need to attach your policies to a role and then attach a role to lambda.
Please read about lambda execution role over here
You can't limit the visibility for the list of all the Lambda Functions (there is also the same "problem" on EC2 Instances and S3 Buckets permissions policy), so your user cannot interact with the Lambda because the policy that you provided have the condition on the specific resource, but he need the full read-only capability even to see the function.
You should add at least an Allow statement on lambda:ListFunctions and lambda:GetAccountSettings for Resource "*" (so on every Lambda of your account), as stated here.
You could also, as documented here, add the standard AWSLambda_ReadOnlyAccess policy to your group.

AWS Cloudformation:Template validation error Role and policy

I am new to cloudformation and trying to create a template that can create a execution role and associated policies for my lambda function.
AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation Template for creating iam role for SSM lambda
Parameters:
rolename:
Type: String
Description: The name of the iam role for SSM Lambda
Default: SSM_lambda_role
policyname:
Type: String
Description: pcluster lambda iam policy for SSM Lambda
Default: SSM_lambda_policy
Resources:
ssmlambdarole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub '${rolename}'
Description: iam role for ssm lambda role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- !Sub 'arn:aws:iam::${AWS::AccountId}:policy/${policyname}'
ssmlambdapolicy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: !Sub '${policyname}'
Description: The name of the iam role for SSM Lambda
Path: '/'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- logs:CreateLogGroup
Resource: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*
Effect: Allow
Sid: CloudWatchLogsPolicy
- Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${policyname}:*
Effect: Allow
Sid: CloudWatchLogsPolicy
- Action:
- ssm:Describe*
- ssm:Get*
- ssm:List*
Resource: "*"
Effect: Allow
If I define a role first in the above template, I get an error during stack creation mentioning that the policy is not found and if I create policy first in the above order, I keep getting a validation error. can someone tell me where am I getting wrong.
There is an attribute that can help to achieve that: DependsOn,
but the better way is to use - !Ref ssmlambdapolicy instead of - !Sub 'arn:aws:iam::${AWS::AccountId}:policy/${policyname}'.
In each case, it will establish a dependency between resources. Thanks to that AWS will be able to recognize resource creation orders - you didn't use any of them, so AWS 1stly tries to create a role (or policy, depending on the order in the template), and attach a policy that doesn't exist yet.
The validation error is due to that you missed !sub in the policy statements.
Btw, I strongly recommend looking for help in CFN documentation - sometimes there is a section with use-case examples.

how to get Rolename from existing Lambda function on cloud via its friendly name or arn using cloudformation?

I have created a CFN template for rotating secret of RDS. It consist of a AWS HostedLambda which calls for an autogenerated Role. I want to attach another policy to that role.
rRotationLambdaDecryptPolicy:
Type: AWS::IAM::ManagedPolicy
DependsOn: rSecretRotationScheduleHostedRotationLambda
Properties:
Description: "Providing access to HostedLambda for decrypting KMS"
ManagedPolicyName: CustomedHostedLambdaKmsUserRolePolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowLambdaDecryptKMS
Effect: Allow
Action:
- kms:Decrypt
- kms:CreateGrant
Resource:
- !Sub arn:aws:kms:*:${AWS::AccountId}:key/*
Condition:
ForAnyValue:StringLike:
kms:ResourceAliases: alias/SecretsManager_KMSKey
Roles: <friendly rolename>
Problem is i know the Lambda friendly name and its Arn. Need to find the rolename linked to this lambda so that i can attach the above policy to it(Add its friendly name to Roles).
tried attaching this below
Roles:
Fn::Join:
- ""
- - '"'
- Fn::GetAtt:
- !Sub 'arn:aws:lambda::${AWS::AccountId}:function:SecretsManager-research-creds-rotation-lambda'
- Role
- '"'
P.S.- cant use importvalue here, because the nested stack has been created by AWS and its output doesn't consist of export.
Lambda used:-
rSecretRotationSchedule:
Type: AWS::SecretsManager::RotationSchedule
Properties:
SecretId:<SecretId>
HostedRotationLambda:
KmsKeyArn: <KmsKeyArn>
MasterSecretArn: <MasterSecretArn>
MasterSecretKmsKeyArn: <MasterSecretKmsKeyArn>
RotationType: PostgreSQLMultiUser
RotationLambdaName: SecretsManager-research-creds-rotation-lambda
VpcSecurityGroupIds: <VpcSecurityGroupIds>
VpcSubnetIds: <VpcSubnetIds>
RotationRules:
AutomaticallyAfterDays: 60
Below is the link from which i took reference for template:-
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-rotationschedule.html
Most likely you can't do this with plain CFN. You would have to develop a custom resource. This would be in the form of a new lambda function which would use AWS SDK to query attributes of your primary lambda function. Once the custom resource finds the role name it would return it to your stack for further use.

Using Existing Role in CloudFormation Template

I'm trying to use an existing IAM role in a CFN template that is already being used by other services.
The Resource definition looks like this:
MyInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: "/"
Roles: ["Capras999"]
And I'm referencing it like this:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Role: !Ref MyInstanceProfile
However I get this error:
1 validation error detected: Value 'capras-cluster-Prsr-DL-with-params-MyInstanceProfile-1R68JNUXU0SAA' at 'role' failed to satisfy constraint: Member must satisfy regular expression pattern: arn:(aws[a-zA-Z-]*)?:iam::\d{12}:role/?[a-zA-Z_0-9+=,.#\-_/]+ (Service: AWSLambdaInternal; Status Code: 400; Error Code: ValidationException; Request ID: 5f75a56d-8ce4-473e-924e-626a5d3aab0a)
What am I doing wrong? Please help me.
For lambda function you need role not instance-profile.
The solution was to copy and paste an existing role's ARN into the template. Other possibility is to pass it in using a parameter.
p.s.
Generally, you need to define AWS::IAM::Role with a thrust policy for lambda. For example:
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: my-lambda-execution-role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: {'Service': ['lambda.amazonaws.com']}
Action: ['sts:AssumeRole']
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSLambdaExecute
Then for your function you would do:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Role: !GetAtt LambdaExecutionRole.Arn
You are specifying the instance name as the value, this parameter should instead be the Arn of the IAM role in question.
From your question you're trying to attach an instance profile to your Lambda, these are for EC2 instances only. Instead you want the Arn of the role itself.
From the console you can get the Arn for IAM role Capras999.
If you're using an existing role make sure to update your AssumeRolePolicy to also include lambda.amazonaws.com (and lambdaedge.amazonaws.com if using it for Lambda#Edge).

CloudFormation, S3 bucket access to cross-acccount IAM role

I have 2 accounts, s3_buck_acct and iam_acct. I want to provision IAM role from iam_acct to certain actions on the S3 bucket from s3_buck_acct.
Here is the CloudFormation template I came up with that ends up with error:
Resources:
S3BucketTest:
Type: AWS::S3::Bucket
Properties:
BucketName: "cross-acct-permission-demo"
LifecycleConfiguration:
Rules:
- Id: LifecycleExpRule
ExpirationInDays: '3650'
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
S3CURBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
!Ref S3BucketTest
PolicyDocument:
Statement:
- Action:
- 's3:ListBucket'
- 's3:ListBucketMultipartUploads'
- 's3:PutObject'
- 's3:GetObject'
Effect: "Allow"
Resource:
- "arn:aws:s3:::cross-acct-perm-demo"
- "arn:aws:s3:::cross-acct-perm-demo/*"
Principal: "arn:aws:iam::1234567890:role/service-role/test-role-20190828T130835"
- Action: "*"
Resource: !Join [ '', ["arn:aws:s3:::", !Ref S3BucketTest, '/*']]
Principal: '*'
Effect: Deny
Condition:
Bool:
'aws:SecureTransport':
- 'false'
Error message:
Invalid policy syntax. (Service: Amazon S3; Status Code: 400; Error Code: MalformedPolicy; Request ID: 91BF8921047D9D3B; S3 Extended Request ID: ZOVOzmFZYN6yB1btOqMqgJjOpzfiUpP86c2XiVylzYkg37fGga8/eYDL7C4WzwhmcDGU7NJkL68=)
Not sure where I got this wrong. Can I provision S3 bucket access to cross-account IAM? From the console permissions section, I was able to do it.
Your bucket is called cross-acct-permission-demo but your policy specifies cross-acct-perm-demo. Also your indentation is not correct for the first Action (though it should not cause this issue). Also not sure if the service-role principle is correct in this context.
If you want IAM users in account A to be able to access resources in account B then you create an IAM role in account B that gives access to the relevant resources in account B, then you define account A as a trusted entity for the IAM role, then you permit access to that role to the relevant users in account A. Those users in account A can now assume the (cross-account) role in account B, and gain access to resources in account B.
See Tutorial: Delegate Access Across AWS Accounts Using IAM Roles