Is it possible to write your custom permissions boundary policy inside the AWS CloudFormation for AWS Lambda's LambdaExecutionRole?
It could be best if I could write all the necessary policies for the LambdaExecutionRole inside this code instead of using !Ref or !Sub.
Please see the PermissionBoundary part
(This code doesn't work because of misconfigured permission boundary part)
LambdaExecutionRole:
Description: Creating service role in IAM for AWS Lambda
Type: AWS::IAM::Role
Properties:
RoleName: !Sub 'CodeStar-${ProjectId}-Execution${Stage}'
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: sts:AssumeRole
Path: /
ManagedPolicyArns:
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
PermissionsBoundary: !Sub
Properties:
PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:DescribeLogGroups
- logs:PutLogEvents
- xray:Put*
Effect: Allow
Resource: '*'
Sadly you can't do this. PermissionsBoundary requires ARN to IAM policy. So first you have to create AWS::IAM::ManagedPolicy and then reference it's ARN in PermissionsBoundary.
Related
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.
So here is the situation:
I have a Cloudformation that creates CodeCommit repositories with some extra resources for other devops processes to work.
I got the requeriment to block users from doing a push to a specific branch, in this case master, I have found the policy that does that. source: https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-conditional-branch.html
So I write a role and policy with the following:
Resources:
CodeCommitRepository:
Type: AWS::CodeCommit::Repository
Properties:
RepositoryName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}'
RepositoryDescription: !Ref CodeCommitRepositoryDescription
Tags:
- Key: fdr:general:project-code
Value: !Ref ProjectCode
- Key: fdr:general:project-name
Value: !Ref ProjectName
DenyPushRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}-DenyPush-Role'
ManagedPolicyArns:
- !Ref DenyPushToMasterPolicy
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- codecommit.amazonaws.com
DenyPushToMasterPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}-DenyPush-Policy'
Description: Policy to deny push to master
PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- codecommit:GitPush
- codecommit:PutFile
- codecommit:DeleteBranch
- codecommit:MergePullRequestByFastForward
Effect: Deny
Resource: !GetAtt CodeCommitRepository.Arn
Condition:
StringEqualsIfExists:
codecommit:References:
- refs/heads/master
'Null':
codecommit:References: 'false'
As I understand which I wouldn't say is much, by creating the Role with the Policy and the sts:AssumeRole I thought that any user using that repository will assume that role that denys them the ability to push to master but that wasn't the case.
I guess that we may be overcomplicating things and we should put that policy unto all users directly on IAM but the idea is to have it done very granular. What am I doing wrong or is it even possible?.
Best regards
DenyPushRole is not for any users. You specified it to be only for codecommit.amazonaws.com which is incorrect.
Users do not automatically assume any roles. They have to explicitly assume your DenyPushRole using AssumeRole API call. Your users must also have permission to sts:AssumeRole.
Thus your role, in a general form, should be:
DenyPushRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}-DenyPush-Role'
ManagedPolicyArns:
- !Ref DenyPushToMasterPolicy
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
AWS:
- !Ref AWS::AccountId
Once the role exist, and the users have sts:AssumeRole to assume it, they will use the AssumeRole command to actually assume the role. This will give then new, temporary AWS credentials to perform any actions specified by the role. In your case, the role only denies, so they will not be able to do anything anyway. You would need to add some allow statements to the role for your uses to be actually able to do something, not only deny.
I am trying to give access permission of secret manager to my lambda function in SAM template but it is giving me error that policy statement is malformed.
Policies:
- Statement:
- Sid: AWSSecretsManagerGetSecretValuePolicy
Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: <arn >
Can some one let me know the correct way of adding policy to my lambda function.
I am using SAM template (Type: AWS::Serverless::Function)
This policy only accepts ARN of a secret, so secret name will not work. https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-template-list.html#secrets-manager-get-secret-value-policy
Below works for me.
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: MyProject/
Handler: app
Policies:
- AWSSecretsManagerGetSecretValuePolicy:
SecretArn: 'arn:aws:secretsmanager:####'
or passing it as a parameter
- AWSSecretsManagerGetSecretValuePolicy:
SecretArn: !Ref RdsSecretArn
There are SAM Policy Templates where one of them is AWSSecretsManagerGetSecretValuePolicy you can use them directly in the definition.
Or if you wanna manage the policies yourself.
QueryFunction:
Type: AWS::Serverless::Function
Properties:
Handler: lambda_handler.lambda
Policies:
- AmazonDynamoDBFullAccess
- AWSLambdaVPCAccessExecutionRole
- SSMParameterReadPolicy:
ParameterName: parameter_name
- Statement:
- Effect: Allow
Action:
- dynamodb:*
Resource: 'resource_arn'
Runtime: python3.7
Try this :
Policies:
- Version: '2012-10-17'
Statement:
- Sid: AWSSecretsManagerGetSecretValuePolicy
Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: <arn >
This policy on the lambda works for me (YAML)
Policies:
- AWSSecretsManagerGetSecretValuePolicy:
SecretArn:
Ref: THE_NAME_YOU_GAVE_YOUR_SECRET_RESOURCE
I'm using an IAM role for a glue job that makes some data processing, to accomplish this task I need to assume the role that executes the glue role.
As example, in the following cloudformation template the IAM::Policy has permission to query from a Dynamo DB table and to get Objects from an s3 bucket.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
GlueAccessPolicy:
Type: AWS::IAM::Policy
Properties:
Roles:
- !Ref GlueRole
PolicyName: glue_access_policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: 's3:getObject'
Resource:
- 's3_bucket_arn'
- Effect: Allow
Action:
- 'dynamodb:DescribeTable'
- 'dynamodb:Query'
Resource:
- 'dynamo_table_arn'
GlueRole:
Type: 'AWS::IAM::Role'
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: 'Allow'
Principal:
Service:
- 'glue.amazonaws.com'
Action:
- 'sts:AssumeRole'
Now, this question illustrates an example to assume role B from role A, switching roles.
So, I have the question if is it possible or valid for GlueRole to assume GlueRole ?
As there is no limitation for the role to assume itself, and the docs state the following
A policy that grants a user permission to assume a role must include a statement with the Allow effect on the following:
The sts:AssumeRole action
The Amazon Resource Name (ARN) of the role in a Resource element
it is straightforward to add this policy to the AWS::IAM::Policy resource on the CloudFormation template.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
GlueAccessPolicy:
Type: AWS::IAM::Policy
Properties:
Roles:
- !Ref GlueRole
PolicyName: glue_access_policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: 'sts:AssumeRole'
Resource: !GetAtt GlueRole.Arn
GlueRole:
Type: 'AWS::IAM::Role'
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: 'Allow'
Principal:
Service:
- 'glue.amazonaws.com'
Action:
- 'sts:AssumeRole'
I have to add retention policy to API Gateway Cloudwatch logs, hence I cannot use the aws provided policy to do so i.e. arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
So instead I created my own role with custom policy :
ApiGatewayCloudWatchLogsRole:
Type: 'AWS::IAM::Role'
DependsOn: APIGFunctionLogGroup
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
Action: 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: APIGatewayPushLogsPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
Effect: Allow
Action:
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'logs:DescribeLogGroups'
- 'logs:DescribeLogStreams'
- 'logs:GetLogEvents'
- 'logs:FilterLogEvents'
Resource: '*'
And then created LogGroup with retention as :
APIGFunctionLogGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
RetentionInDays: 30
LogGroupName: !Join
- ''
- - API-Gateway-Execution-Logs_
- !Ref MyRestApi
And passed the above created role to AWS::ApiGateway::Account
ApiGatewayAccount:
Type: 'AWS::ApiGateway::Account'
DependsOn: APIGFunctionLogGroup
Properties:
CloudWatchRoleArn: !GetAtt
- ApiGatewayCloudWatchLogsRole
- Arn
But while deploying my API Gateway I am getting error as :
I have the trust policy as well but API Gateway Account is not getting created.
If you create the log group yourself, before APIgateway does you should be able to use the existing policy/service role.