adding CloudWatch to a stack with CloudFormation - amazon-web-services

I am currently in charge of adding CloudWatch integration to an already made Cloud Formation stack.
We create the stacks through CLI, but at the moment we add CloudWatch manually afterwards.
What i need is to automatically activate CloudWatch for instances and monitor CPU, hdd and so on through the use of CloudFormation templates.
Thanks in advance!

My suggestion is that you don't add new CloudWatch items to the existing CloudFormation stack. Instead, create a CF template with the appropriate metrics and deploy from this template for each instance you want to monitor.
From there, I suggest you create an AWS Lambda function that will receive an Instance Id as input and will deploy a CloudFormation stack against the instance. You should enable CloudTrail on your account and create a Rule to match any RunInstances event on the account and trigger the Lambda function.
Keep in mind the default limit for CloudFormation stacks is 200. You might need to request an increase depending on your use case.

Related

Update cloudwatch alarm threshold based on the stoarge size of RDS

We have a setup where RDS is provisioned through terraform, cloudwatch alarm for RDS' free storage space metric is set to <10% total RDS storage through terraform. Total RDS storage is a static value. Whenever there's storage shortage we manually increase the RDS storage through AWS console. Is there way to update the cloudwatch alarm threshold automatically, to set it to 10% of new total storage after increasing RDS storage?
Although considered an anti-pattern, there is an alternative. It is considered an anti-pattern because it is generally a bad idea to have two different processes controlling the configuration of the same resource. However, if you insist on controlling the size of the RDS outside the terraform plan, you can automate the cloudwatch metric settings.
The root problem is that the FreeSpaceAvailable RDS metric only understands bytes, not percentages. Terraform does that conversion for you so you don't see it. That is why the alarm is not changing when you change the allocated space in the RDS console. You could develop a simple lambda function that uses one the of the AWS APIs (like boto3 for python) to periodically query the size the RDS database and update the alarm on FreeSpaceAvailable accordingly. It could be even more sophisticated by having SNS notify a SQS queue about changes in RDS configuration which could then trigger the lambda to evaluate the metric, which would make the update very fast and efficient. You would need to apply a IAM policy which allows the lambda to read data on the RDS instance in question and permission to update the metric in question. Alternatively, you could have it be manually run and then run it right after the AWS console update, but in that case you could probably just as easily manually update the metric yourself.
I still wouldn't recommend this be the path due to the control of an already controlled resource by terraform.
This should be automatically updated by terraform if you use terraform code to update the allocated space. Cloudwatch itself doesn't understand the relationship between what you are watching - it is just programmed with a threshold value by terraform when you apply the template. Since terraform is doing both actions on your behalf (allocating the RDS instance and setting up cloudwatch metrics) it understands what needs to be set. However, using the AWS console is essentially side-stepping the terraform. While the size increases, terraform is unaware of the change to also change the cloudwatch metric. Using terraform to apply the size update should fix the alarm, depending on how you setup your alarm threshold.

Dynamically tagging of AWS resources

I'm new to this and I'd like to get some ideas in terms of a code that can dynamically tag AWS resources. I'm confuse as to what will trigger the execution of the code that will tag it. Can someone please point me to right resources and sample codes?
You need to monitor CloudTrail events for creation of resources you would like to tag and invoke a Lambda function for the matching events, which tags
the resources accordingly.
CloudWatch Event Rule is setup to monitor :create* API calls via CloudTrail.
This rule triggers the lambda function whenever a matching event found.
The Lambda function fetches the resource identifier and principal information from the event and tags the resources accordingly.
I've devised a solution to tag EC2 resources for governance. It is developed in CDK Python and uses Boto3 to attach tags.
You can further extend this code to cover other resource types or maintain a DynamoDb table to store additional tags per principal
such as Project, Team, Cost Center. You can then simply fetch the tags of a principal and apply them all at once.
You can write lambda functions and use Cloudwatch events to trigger that function which will assign tag to your resources.
You can use AWS nodejs-sdk or boto3 for Python.

AWS- Does modyfing lambda update the CloudFormation Stack instantly?

Lets say I have a CloudFormation stack running, which creates and deploys an Lambda function. In the AWS Console, if I connect my Lambda function to an API in API Gateway, will my CloudFormation Template be updated immediately if the Lambda function successfully integrates with the API?
It's a one way traffic from Cloudformation to resources.
Meaning if you modify your Cloudformation template and update the stack then the resources that were created by Cloudformation get modified/updated. However the other way is not true. Meaning if you modify your resources the Cloudformation template does not get updated.
Moreover, as a good practice you should avoid modifying the resources directly because you may end up breaking the Cloudformation's update stack functionality for that that stack

Run AWS Lambda code when creating a new AWS EC2 instance

I'd like to run some code using Lambda on the event that I create a new EC2 instance. Looking the blueprint config-rule-change-triggered I have the ability to run code depending on various configuration changes, but not when one is created. Is there a way to do what I want? Or have I misunderstood the use case of Lambda?
We had similar requirements couple of days back(Users were supposed to get emails whenever a new instance gets launched)
1) Go to cloudwatch, then select Rules
2) Select service name (its ec2 for your case) then select "Ec2 instance state-change notification"
3) Then select pending in "Specific state" dropdown
4) Click on Add target option and select your lambda function.
That's it, whenever a new instance gets launched, Cloudwatch will trigger your lambda function.
Hope it helps !!
You could do this by inserting code into your EC2 instance launch userdata and have that code explicitly invoke a Lambda function, but that's not the best way to do it.
A better way is to use a combination of CloudTrail and Lambda. If you enable CloudTrail logging (every a/c should have this enabled, all the time, in all regions) then CloudTrail will log to S3 all of the API calls made in your account. You then connect this to Lambda by configuring S3 to publish events to Lambda. Your Lambda function will receive an S3 event, can then retrieve the API logs, find RunInstances API calls, and then do whatever work you need to as a consequence of the new instance being launched.
Some helpful references here and here.
I don't see a notification trigger for instance startup, however what you can do is write a startup script and pass that in via userdata. That startup script would need to download and install the AWS CLI and then authenticate to SNS and publish a message to a pre-configured topic. The startup script would authenticate to SNS and whatever other AWS services are needed via your IAM Role, so you would need to give the IAM Role permission to do whatever you want the script to do. This can be done in the IAM console.
That topic would then have your Lambda function subscribed to it, which would execute. Similar to the below article (though the author is doing something similar for shutdown, not startup).
http://rogueleaderr.com/post/48795010760/how-to-notifyemail-yourself-when-an-ec2-instance
If you are putting the EC2 instances into an autoscale group, I believe there is a trigger that gets fired when the autoscale group launches a new instance, so you could take advantage of that.
I hope that helps.
If you have CloudTrail enabled, then you can have S3 PutObject/TrailBucket trigger a Lambda function. Lambda function parses the object that is passed to it and if it finds RunInstances event, then run your code.
I do the exact same thing to notify certain users when a new instance is launched. With Lambda/Python, it is ~20 lines of code.

How to send SNS notification after cloud formation is completed?

Is it possible to send a SNS notification after the CFT completion in AWS ? Is there any way to get the progress of the launching CFT in AWS.
When create resources using a CF template there is an Advanced section of the Options menu. From there you can set Notification options using SNS and Topics.
When you start the CF process you can also view the status and importantly where the template might have failed.
You cannot specify notification ARNs via a CloudFormation template itself. You can specify them if you use the console to create the stack creation. But you cannot use the console to update the ARNs once the stack has been created. You can, however, use aws-cli to update the stack with notifications ARNs once it has been created, eg:
aws cloudformation update-stack --stack-name stack-name --use-previous-template --notification-arns "arn:aws:sns:us-east-1:${ACCOUNT_ID}:${TOPIC_NAME}"
Replace the variable ${VARIABLE} with the literal values from your account.
There's also knowledge center article from AWS where you can replace ROLLBACK_IN_PROGRESS statement with any other state of CloudFormation to get SNS Notification.
You can trick CloudFormation into sending SNS messages from inside the template:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html
Custom resources enable you to write custom provisioning logic in
templates that AWS CloudFormation runs anytime you create, update (if
you changed the custom resource), or delete stacks. For example, you
might want to include resources that aren't available as AWS
CloudFormation resource types. You can include those resources by
using custom resources. That way you can still manage all your related
resources in a single stack.
Use the AWS::CloudFormation::CustomResource or Custom::String resource
type to define custom resources in your templates. Custom resources
require one property: the service token, which specifies where AWS
CloudFormation sends requests to, such as an Amazon SNS topic.