i created a log group for my lambda using cloud formation, and i when i run my cloudformation scripts, the lambda function includes the cloudwatch log trigger. When i invoke the lambda, the log group i created using the cloudformation doesn’t have any log stream in it, but it seems cloudformation automatically creates a log group for the lambda regardless if i am creating one using cloudformation and including it to the function.
Is there any advice please?
'''
resources:
Resources:
AccessLogs:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/lambda/${self:service}-dev-AccessLogs
RetentionInDays: 7
LambdaExecutionRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Policies:
- PolicyName: logpolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
Resource: '*'
- Effect: Allow
Action:
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
'''
You cannot assign an arbitrary log group to a Lambda function. There's an open Feature Request for it.
If you simply want to change the log retention policy then you might be able to do that using this technique, but it still does not allow you to control the log group name.
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.
I want to add AWS managed policy (AmazonSSMFullAccess) to a role using CloudFormation.
I tried to use AWS::IAM::ManagedPolicy but it creates a Customer Managed policy and I don't want that. I want it to be AWS managed.
Do you have any idea how can I do that?
I am trying to add AWS managed AmazonSSMFullAccess and here is the code I am using in mu CF template:
AmazonSSMFullAccess:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'cloudwatch:PutMetricData'
- 'ds:CreateComputer'
- 'ds:DescribeDirectories'
- 'ec2:DescribeInstanceStatus'
- 'logs:*'
- 'ssm:*'
- 'ec2messages:*'
Resource: '*'
- Effect: Allow
Action: 'iam:CreateServiceLinkedRole'
Resource: >-
arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*
Condition:
StringLike:
'iam:AWSServiceName': ssm.amazonaws.com
- Effect: Allow
Action:
- 'iam:DeleteServiceLinkedRole'
- 'iam:GetServiceLinkedRoleDeletionStatus'
Resource: >-
arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*
- Effect: Allow
Action:
- 'ssmmessages:CreateControlChannel'
- 'ssmmessages:CreateDataChannel'
- 'ssmmessages:OpenControlChannel'
- 'ssmmessages:OpenDataChannel'
Resource: '*'
You can't create AWS managed policies, because only AWS can do it. You, as an AWS customer can only create customer managed policies.
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!
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.
In my aws account, there is having a 250+ SNS and SQS i need to migrate one region to another region using cloudformation, any one can help to write a script using yaml
Resources:
T1:
Type: 'AWS::SNS::Topic'
Properties: {}
Q1:
Type: 'AWS::SQS::Queue'
Properties: {}
Q1P:
Type: 'AWS::SQS::QueuePolicy'
Properties:
Queues:
- !Ref Q1
PolicyDocument:
Id: AllowIncomingAccess
Statement:
-
Effect: Allow
Principal:
AWS:
- !Ref AWS::AccountId
Action:
- sqs:SendMessage
- sqs:ReceiveMessage
Resource:
- !GetAtt Q1.Arn
-
Effect: Allow
Principal: '*'
Action:
- sqs:SendMessage
Resource:
- !GetAtt Q1.Arn
T1SUB:
Type: 'AWS::SNS::Subscription'
Properties:
Protocol: sqs
Endpoint: !GetAtt Q1.Arn
TopicArn: !Ref T1
You can try using Former2 which is an open-sourced tool to:
Former2 allows you to generate Infrastructure-as-Code outputs from your existing resources within your AWS account. By making the relevant calls using the AWS JavaScript SDK, Former2 will scan across your infrastructure and present you with the list of resources for you to choose which to generate outputs for.