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
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 just implemented a lambda resolver in AWS AppSync. The lambda and AppSync live in different projects; The template that provisions the function writes the function ARN to SSM and the template that builds AppSync pulls that SSM parameter down and assigns that ARN to an AdditionalAuthenticationProvider.
The deploy process goes in order synchronously; Lambda (create auth function, set ARN to SSM param) -> AppSync (create API, retrieve SSM param and assign to authorization provider).
When I examine the console, I can see the correct function ARN is assigned as the authentication provider to AppSync.
The problem: when I go to issue a request, the lambda is never invoked, I can check CloudWatch and verify no invocations - I am just met with the response.
{
"errors" : [ {
"errorType" : "BadRequestException"
} ]
}
If I do not provide a value to the authorization header, I get a 401 - which is the expected behavior of the lambda authorization directive, rejecting any requests without a value in that header before proceeding to the function.
So it would appear that something isn't plumbed correctly, something is missing that I can't find in a doc to allow invocation.
The gotcha: if I go into the console and assign this same function ARN manually, everything works fine and stays working fine. It would seem that, perhaps, the console is doing something behind the scenes that my deploy is not, but I cannot seem to correctly identify what is missing.
I've been following this document https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#aws-lambda-authorization and one note gives me pause - and I have set these trust permissions, AFAIK.
Lambda functions used for authorization require a principal policy for appsync.amazonaws.com to be applied on them to allow AWS AppSync to call them. This action is done automatically in the AWS AppSync console
Here is the SAM template (without input params)
Resources:
ServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [ lambda.amazonaws.com, appsync.amazonaws.com ]
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: logs
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
- Effect: Allow
Action:
- xray:*
Resource: "*"
- PolicyName: ssm
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ssm:*
Resource: "*"
LambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref AuthorizationFunction
Action: lambda:Invoke
Principal: appsync.amazonaws.com
AuthorizationFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: <code-uri>
Handler: app.lambda
Runtime: nodejs14.x
Role: !GetAtt ServiceRole.Arn
Tracing: Active
FunctionARNParameter:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: <name>
Value: !GetAtt AuthorizationFunction.Arn
Maybe typing it out my problem was just what I needed. The last thing I tried, LambdaPermission was the key - but the action was incorrect and needed to be InvokeFunction.
I also chose to assign the FunctionName as the lambda ARN instead of the name
LambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt PPSAuthorizationFunction.Arn
Action: lambda: InvokeFunction # <--
Principal: appsync.amazonaws.com
Hope this is useful to someone!
This is my cft for lambda, I upload the jar file to s3 and then upload to lambda through s3, I completed the LambdaRole and LambdaFunction section, in the permission section, what should be the SourceArn? I went through the lambda official doc but didn't find any example.
Also, can anyone take a look to see if this cft is correct or not? Thanks!
ConfigurationLambdaRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: 'configuration-sqs-lambda'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- events.amazonaws.com
- s3.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSQSFullAccess
- arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
ConfigurationLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Description: 'configuration service with lambda'
FunctionName: 'configuration-lambda'
Handler: com.lambda.handler.EventHandler::handleRequest
Runtime: Java 11
MemorySize: 128
Timeout: 120
Code:
S3Bucket: configurationlambda
S3Key: lambda-service-1.0.0-SNAPSHOT.jar
Role: !GetAtt ConfiguratioLambdaRole.Arn
ConfigurationLambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName:
Fn::GetAtt:
- ConfigurationLambdaFunction
- Arn
Action: 'lambda:InvokeFunction'
Principal: s3.amazonaws.com
SourceArn: ''
You are creating a Role to run your lambda, a lambda function, and permissions for something to invoke that lambda. The SourceArn is the thing that will invoke the lambda. So in your case it sounds like you want an S3 bucket to invoke the lambda, so the SourceArn would be the ARN of the S3 bucket.
This tutorial relates to what you are doing--specifically step 8 under the "Create the Lambda function" section.
Your CF template generally looks correct. The only thing I see that will be assuming this role is lambda.amazonaws.com, so the role may not need to list the following in the AssumeRolePolicyDocument section:
- events.amazonaws.com
- s3.amazonaws.com
Also see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html
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.