aws lambda permission to IAM usergroup using cloudformation - amazon-web-services

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.

Related

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.

Possible to create a policy and share the policy to role across multiple accounts

I am trying to create a policy in one AWS account and need to share that policy to a role in multiple accounts (Prod, Dev, Sandbox).
And I can add the AWS accounts number manually and assign AWS Managed Policy to roles and needs to create multiple roles as well.
How can we achieve this?
Here is the code I wrote
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Create a role that authorizes access to users in another account'
Metadata:
Version: 0.7
Parameters:
RoleName:
Type: String
Default: R_EC2-Describe-Instance
MainAccountId:
Type: String
Description: >-
Include the Managed Services Account ID(the account ID where the Main VPC is registered)
Default: 111111111111
MaxLength: 12
MinLength: 12
Resources:
AssumeRole:
Type: AWS::IAM::Policy
Properties:
RoleName: !Ref RoleName
Policies:
-
PolicyName: "CoreSVC-Describe-EC2"
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- 'sts:AssumeRole'
Resource: !Join [ "", [ "arn:aws:iam::", !Ref MainAccountId, ":role/R_EC2-Describe-Instance" ] ]
AssumeRolePolicyDocument:
Version: '2012-10-17'
ManagedPolicyName:
- "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAcess"
Statement:
- Effect: Allow
Principal:
"AWS": !Join [ "", [ "arn:aws:iam::", !Ref MainAccountId, ":root" ] ]
Action:
- sts:AssumeRole
Condition: {}
You can't share an IAM Policy with other accounts, as it doesn't have a resource policy to allow it.
The code sample you've shared is sharing the IAM Role with multiple accounts, which is possible via the role's resource/trust policy.
If you want to share the same policy across multiple accounts, then you should probably use CloudFormation StackSets (as mentioned by #ervin-szilagyi), or some other infrastructure-as-code approach.
If you want to share the role with other accounts, then you've already done it. All that's missing is role in those accounts with access to the sts:AssumeRole action so that it can assume the role you've shared in your code.

How to reference AWS managed policy arn in cloudformation?

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.

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

Edit AWS Cognito Identity Pool using serverless.yml

I am configuring an AWS Cognito Identity Pool using the severless framework, and I am editing a file in the yml configuration to add an unauthenticated role for users to upload an image to an s3 bucket.
The code was previously deployed without an unauthenticated role being specified, and the deployment went fine and was stable. After I went looking for a way to control the permissions regarding accessing the S3 bucket, I discovered that the only way to give write, but not read, permissions on an S3 bucket is to specify it in a user policy, so I have to add an unathenticated role to the identity pool. However, when I deploy the code, I get an error stating:
Serverless Error ---------------------------------------
An error occurred: CognitoIdentityPoolRoles - Resource cannot be updated.
I have managed to get around the problem in the dev environment but it required totally deleting the stack and rebuilding it from scratch.
I also do not want to go in and adjust the resources manually in the AWS console since resources should be managed in cloudformation or in the console, but doing it both ways leads to chaos.
So, at the moment, the options I see are to delete the entire stack and rebuild it with the new roles, or find a way to update through cloudformation.
Does anyone have a way to avoid the first option and allow me to update the stack without attaching the role in the console?
Relevant section of serverless.yml is below...
Resources:
# The federated identity for our user pool to auth with
CognitoIdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
# Generate a name based on the stage
IdentityPoolName: ${self:custom.stage}MyIdentityPool
# Allow unathenticated users
AllowUnauthenticatedIdentities: true
# Link to our User Pool
CognitoIdentityProviders:
- ClientId:
Ref: CognitoUserPoolClient
ProviderName:
Fn::GetAtt: [ "CognitoUserPool", "ProviderName" ]
# IAM roles
CognitoIdentityPoolRoles:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId:
Ref: CognitoIdentityPool
Roles:
authenticated:
Fn::GetAtt: [CognitoAuthRole, Arn]
# Next two lines are the 2 lines of code which break everything
unauthenticated:
Fn::GetAtt: [CognitoUnAuthRole, Arn]
# IAM role for UN-authenticated users
CognitoUnAuthRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Principal:
Federated: 'cognito-identity.amazonaws.com'
Action:
- 'sts:AssumeRoleWithWebIdentity'
Condition:
StringEquals:
'cognito-identity.amazonaws.com:aud':
Ref: CognitoIdentityPool
'ForAnyValue:StringLike':
'cognito-identity.amazonaws.com:amr': unauthenticated
Policies:
- PolicyName: 'CognitoUnAuthorizedPolicy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action:
- 'mobileanalytics:PutEvents'
- 'cognito-sync:*'
- 'cognito-identity:*'
Resource: '*'
# Allow users to upload attachments to their
# folder inside our S3 bucket
- Effect: 'Allow'
Action:
- 's3:PutObject'
Resource:
- Fn::Join:
- ''
-
- Fn::GetAtt: [MediafilesBucket, Arn]
- '/submissions/'
Fixed.
I commented out the sections of serverless.yml related to the identity pool deployed (destroyed), then uncommented that section, redeployed, and restored from backup.
It seems to be a bit of a hack, but it worked.
I also feel like there should be a way to edit identity pool roles through cloudformation...