Update logGroup retention for existing logs in CloudWatch using CloudFormationTemplate - amazon-web-services

I'm trying to update the logs retention of existing log groups created by my Lambda functions in CloudWatch using the CloudFormationTemplate in YAML.
In order to do that, I set
LambdaCWRetentionPermissionsPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- "logs:PutRetentionPolicy"
Resource:
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*"
LambdaCWRetentionPolicy:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/aws/lambda/*"
RetentionInDays: 14
But it does not seem to work, because it seems to try to create new log groups and they already exist. Is there a way that I can update the retention of already existing logs from CloudFormationTemplate in YAML?

CloudFormation has the function of importing existing resources. After importing, you can update the retention with the CloudFormation stack.
Bringing existing resources into CloudFormation management - AWS CloudFormation
If you created an AWS resource outside of AWS CloudFormation management, you can bring this existing resource into AWS CloudFormation management using resource import.

Related

AWS CloudFormation - Attach existing managed policy to existing role through a template

I am deploying a CloudFormation template to AWS. A role for my Lambda invocation is being created by a template that I am importing, and I cannot modify it directly. I wish to modify that role to attach the AWS managed policy AWSLambdaVPCAccessExecutionRole that already exists in my AWS account. So far, all of my searches have come up empty.
I have found instructions for how to create a new role with an existing managed policy
I have found instructions for how to create a new policy and attach it to an existing role.
I have found instructions for how to Update a Stack using the AWS console or the CLI, but not via a template (YAML or JSON)
I have found instructions for calling something called aws_iam_role_policy_attachment in something called Terraform, but that is not available to me
I am hoping for something like the following but I cannot find any evidence of this existing anywhere. Is there anything that can do what I am trying to do?
---
Resources:
AdditionalRolePermissions:
Type: "AWS::IAM::RolePolicyAttachment"
Properties:
Roles:
- Ref: ExistingRole
PolicyName:
- Ref: ExistingPolicy
The best solution I have come up with so far is to create a new policy that has a manually created PolicyDocument that is the same as the existing one for AWSLambdaVPCAccessExecutionRole and attach it to the role upon creation. I would prefer not to do that though because it will be harder to maintain.
Unfortunately, you can not do this in pure CloudFormation unless you create a custom resource but this isn't really pure CloudFormation at that point as you'd need to create a lambda and other resources to implement the custom resource. There is no concept of a policy attachment in CloudFormation presently and these attachments only happen when you define a policy or role resource.
The simplest thing would be to go with your solution of creating a policy that duplicates AWSLambdaVPCAccessExecutionRole. That policy is fairly simple and shouldn't clutter up your CloudFormation template too much compared to some other complicated policies.
It is possible as of 2021. Please see: https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-attach-managed-policy/
Example:
AWSTemplateFormatVersion: '2010-09-09'
Description: something cool
Resources:
IAM:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
RoleName: some_role_name
Policies:
['arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole']

Creating a AWS WorkMail Lambda invoke permission in CloudFormation

When I create a Lambda::Permission resource in Cloudformation I have an issue with validating the principal. Currently I have it set to use the !Sub function and that's not a valid principal according to CloudFormation. Does any one have any experience with creating a workmail invoke permission?
AWSTemplateFormatVersion: 2010-09-09
Resources:
WorkmailInvokePermission:
Type: 'AWS::Lambda::Permission'
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: arn:aws:<region>:<function_arn>
Principal: !Sub workmail.${AWS::Region}.amazonaws.com
Outputs: {}
I figured it out, it was a pretty simple, the problem was I was in a region where Workmail wasn't actually available so it ended up creating an error.

How to attach AmazonEC2RoleforSSM to ec2 instance in a CloudFormation script

I am trying to bring up multiple ec2 instances cloudformation script. I am using a shell script to loop the aws cloudformation create-stack command and successfully bringing up multiple instances.
Now I need to bring these instance up with the SSM Role attached. However I don't see any way of using an existing role in the script. I need to re-create the role inside the script thus:
AWSTemplateFormatVersion: 2010-09-09
Description: Compact template for creating an ec2 instance for SPT
Resources:
IAMRole:
Type: AWS::IAM::Role
Properties:
RoleName: SPTvacmRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM
InstanceProfile1:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- Ref: IAMRole
ec2instance1:
Type: AWS::EC2::Instance
Properties:
SubnetId: subnet-0da86f65478f3d30a
KeyName: spt-lab
ImageId: ami-00344ae218e7aae62
InstanceType: t2.nano
IamInstanceProfile: !Ref InstanceProfile1
SecurityGroupIds:
- sg-0d3fae6860ce71c91
This can be executed only once, because by the time the loop executes the command for a second time, the role SPTvacmRole already exists and the stack fails.
I've already created a role from the console manually, using the AmazonEC2RoleForSSM Policy and named it EC2RoleForSSM, however when I try to reference that role by its name -Ref: EC2RoleForSSM in InstanceProfile1 without creating IAMRole, it gives an error saying Template format error: Unresolved resource dependencies [EC2RoleForSSM] in the Resources block of the template
How can I use the pre-existing role EC2RoleForSSM in the script, without having to create it again?
You should not include a Ref function as this is used for retrieving values from parameters or resources.
Instead just use the string EC2RoleForSSM like below.
InstanceProfile1:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- EC2RoleForSSM
However I don't see any way of using an existing role in the script. I need to re-create the role inside the script
How can I use the pre-existing role EC2RoleForSSM in the script, without having to create it again?
If the role exists, you can't create the same role in CloudFormation. Instead, you should import it:
Bringing existing resources into CloudFormation management
AWS::IAM::Role is one of the resources that can be imported into CloudFormation.
If you just want to reference it in the templates, #ChrisWilliams already explained how to do it.

Configuring logging of AWS API Gateway

I created a lambda function to upload files to s3. When testing via the AWS interface, everything works. Next I created the API Gateway and tried to make a request through ReactJs. But I get an error. I want to see what error occurs but I cannot add logs to the API Gateway. What I do.
Create API Gateway -> go to Stages-> Logs/Tracing
Try to activate checkbox Enable CloudWatch Logs but got CloudWatch Logs role ARN must be set in account settings to enable logging
Create role in IAM with next policy: AmazonS3FullAccess, AmazonAPIGatewayPushToCloudWatchLogs, AWSLambdaBasicExecutionRole
Copy the Role ARN
go to the setting of my api and try to paste to CloudWatch log role ARN. But got The role ARN does not have required permissions set to API Gateway.
Can you tell me what other settings I need?
According to this documentation (https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudwatch-logs/) after creating the Role, you need to add it to the Global AWS Api Gateway Settings (when you open the Console, there is a settings menu in the left pane) as the CloudWatch log role ARN.
Then it will use that role for all the gateways you create, so this is a one-time step.
Using a SAM template
You can automate all your deployment process using Serverless Application Model (SAM) or Serverless Framework. The following SAM template defines the Api Gateway and required configuration to enable CloudWatch Logs:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
DependsOn: ApiCWLRoleArn
Properties:
StageName: prod
MethodSettings:
- LoggingLevel: INFO
MetricsEnabled: True
ResourcePath: '/*' # allows for logging on any resource
HttpMethod: '*' # allows for logging on any method
Auth:
ApiKeyRequired: true # sets for all methods
ApiCWLRoleArn:
Type: AWS::ApiGateway::Account
Properties:
CloudWatchRoleArn: !GetAtt CloudWatchRole.Arn
# IAM Role for API Gateway + CloudWatch Logging
CloudWatchRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
Action: 'sts:AssumeRole'
Effect: Allow
Principal:
Service: apigateway.amazonaws.com
Path: /
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs'

How to setup Cloudwatch log for a Lambda created in Cloudformation

After creating a Lambda function in Cloudformation, I would like to be able to setup the Cloudwatch Logs expiration in the same Cloudformation script.
eg:
MyLambdaRole:
Type: AWS::Iam::Role
...
Properties:
...
Policies:
-
PolicyName: "myPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "arn:aws:logs:*:*:*"
MyLambda:
Type: AWS::Lambda::Function
Properties:
...
Role: !GetAtt [ MyLambdaRole, Arn ]
However, CloudFormation does not allow to modify/update Logs that are reserved for AWS: "Log groups starting with AWS/ are reserved for AWS."
Is there a workaround for this? Since there is no way to setup the log name in the Lambda resource creation, maybe there is some way to specify it in the Role definition I can't find.
Try this and use RetentionInDays attribute to change the logs expire after time
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join ['/', ['/aws/lambda', !Ref MyLambda]]
RetentionInDays: 7 # days
Note: the issue of the LogGroup failing to create will appear if the log group name already exists( will exist if MyLambda already exists). The workaround would be to delete and create stack.
No, there is not. As you wrote, it's a log group owned by AWS and you can't give yourself more permissions in a role than AWS would allow. Therefore, you can't allow yourself to modify their log group.
Use the AWS Serverless application Model, takes care of the deployment, roles and logs outbox and you always can add your custom cloudformation code https://github.com/awslabs/serverless-application-model
they already have a lot of examples ready to go.