lambda-ec2-route53.yaml
---

Lambda Function CloudFormation Deployment

This CloudFormation template will deploy a Lambda functions to enrich CloudWatch Alarms.

AWSTemplateFormatVersion: '2010-09-09' Description: "UITS Account Foundation: Lambda EC2 Route53 Records"

Metadata

Metadata is mostly for organizing and presenting Parameters in a better way when using CloudFormation in the AWS Web UI.

Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Tags Parameters: - FunctionS3Bucket - FunctionS3Path ParameterLabels: FunctionS3Bucket: default: 'S3 Bucket Name:' FunctionS3Path: default: 'S3 Code Path:'

Parameters

These are the input parameters for this template. All of these parameters must be supplied for this template to be deployed.

Parameters:

The S3 bucket name where the Lambda functions live. This is used to create an IAM access policy to permit the application EC2 instances access to the S3 bucket.

FunctionS3Bucket: Description: S3 Bucket containing the Lambda functions. Just the bucket name, not a full arn. Default: ua-uits-ecs-public Type: String

S3 path to the zip file containing the code.

FunctionS3Path: Description: Bucket Key for the Lambda Function, ie 'lambda-base' Default: lambda Type: String

Resources

These are all of the resources deployed by this stack.

Resources:

OpsWorks Tagging

This function will tag any EC2 instances created via OpsWorks with Tag data from the custom JSON on the parent OpsWorks stack.

LambdaFunction: Type: AWS::Lambda::Function DependsOn: - SleepDelay Properties:

Be sure to update the handler with the correct file name and function name!

Handler: lambda_ec2_route53.lambda_handler Description: EC2 Instance Created-By Tagging Role: !GetAtt LambdaExecutionRole.Arn Code: S3Bucket: !Ref FunctionS3Bucket S3Key: !Sub "${FunctionS3Path}/lambda-ec2-route53.zip" S3ObjectVersion: "h5zEt8EWEvq_qhT6MZcSobuq.I_l2B99" Runtime: python2.7 Timeout: '60' Environment: Variables: AlertSNSTopic: !ImportValue fdn-logging-alarm-topic

Sleep Delay

This 'resource' calls a Lambda function to simply sleep for 30 seconds. This ensures that the LambdaExecutionRole has finished fully being created so that we can then create the lambda function itself.

SleepDelay: Type: Custom::SleepDelay DependsOn: - LambdaExecutionRole Properties: ServiceToken: !ImportValue foundation-SleepDelayFunction-arn

CloudWatch Logs Group

Create a CloudWatch Log Group for this Lambda function to log to. This allows us to set the retention timeframe.

LambdaLogGroup: Type: "AWS::Logs::LogGroup" DependsOn: - LambdaFunction Properties: LogGroupName: !Sub "/aws/lambda/${LambdaFunction}" RetentionInDays: 7

Lambda Execution Role

This is the IAM role that will be used by Lambda when trying to execute this function. Anything the lambda function needs to do with AWS needs to be allowed in here.

LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: s3policy PolicyDocument: Version: '2012-10-17' Statement: - Sid: s3policy Effect: Allow Action: - s3:GetObject - s3:ListBucket Resource: !Sub "arn:aws:s3:::${FunctionS3Bucket}/*" - PolicyName: cloudwatch-logs-access PolicyDocument: Version: '2012-10-17' Statement:

Let this Lambda fn create a log group if needed

- Sid: cloudwatchloggroup Effect: Allow Action: - logs:CreateLogGroup - logs:Describe* Resource: - "*"

Let this Lambda fn write logs to its own group

- Sid: cloudwatchlogsput Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: - "*" - PolicyName: route53-access PolicyDocument: Version: '2012-10-17' Statement:

Let this Lambda fn update route53 entries

- Sid: route53update Effect: Allow Action: - route53:ListHostedZones - route53:ListHostedZonesByName - route53:ChangeResourceRecordSets Resource: - "*" - PolicyName: ec2-access PolicyDocument: Version: '2012-10-17' Statement:

Let this Lambda fn read EC2 Tags

- Sid: ec2access Effect: Allow Action: - ec2:DescribeTags Resource: - "*"

CloudWatch Event Rule

This creates a CloudWatch Event Rule to listen for ec2:RunInstance events and then invoke our lambda function.

EventRule: Type: "AWS::Events::Rule" DependsOn: - LambdaFunction Properties: Description: "EventRule" EventPattern: detail-type: - "AWS API Call via CloudTrail" detail: eventSource: - "ec2.amazonaws.com" eventName: - "RunInstances" State: "ENABLED" Targets: - Arn: !GetAtt LambdaFunction.Arn Id: "TargetFunctionV1"

Lambda Invokation Permission

This allows SNS to invoke this lambda function

PermissionForEventsToInvokeLambda: Type: "AWS::Lambda::Permission" Properties: FunctionName: !Ref LambdaFunction Action: "lambda:InvokeFunction" Principal: "events.amazonaws.com" SourceArn: !GetAtt EventRule.Arn

Outputs

Output values that can be viewed from the AWS CloudFormation console.

Outputs: LambdaFunction: Value: !Ref LambdaFunction LambdaARN: Value: !GetAtt LambdaExecutionRole.Arn LambdaRole: Value: !Ref LambdaExecutionRole