Last active
February 12, 2021 01:53
-
-
Save dennisroche/287915ca6a0874157d71b0903ec3999b to your computer and use it in GitHub Desktop.
CloudFormation custom resource to create HTTP2 Target Group
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Uses crhelper https://github.com/aws-cloudformation/custom-resource-helper | |
Requires | |
- 'elasticloadbalancing:*' | |
- 'ec2:DescribeInternetGateways' | |
- 'ec2:DescribeVpcs' | |
''' | |
from crhelper import CfnResource | |
import logging | |
import boto3 | |
import uuid | |
from time import sleep | |
logger = logging.getLogger(__name__) | |
helper = CfnResource(json_logging=True, log_level='DEBUG', | |
boto_level='CRITICAL') | |
try: | |
elb = boto3.client('elbv2') | |
except Exception as e: | |
helper.init_failure(e) | |
def without_service_token(event): | |
'''Remove ServiceToken from the CloudFormation `event` to so it can be splatted into boto3''' | |
return {k: event[k] for k in event if k not in {"ServiceToken"}} | |
def convertToInt(key, dict): | |
if key in dict: | |
dict[key] = int(dict[key]) | |
def generateName(prefix): | |
return '{}-{}'.format(prefix[0:19], uuid.uuid4().hex.upper()[0:12]) | |
@helper.create | |
@helper.update | |
def create(event, context): | |
if (event['RequestType'] == 'Update'): | |
try: | |
logger.info('Replacing target group {}'.format( | |
event['PhysicalResourceId'])) | |
elb.delete_target_group(TargetGroupArn=event['PhysicalResourceId']) | |
except Exception as e: | |
logging.critical(e, exc_info=True) | |
pass | |
request = without_service_token(event['ResourceProperties']) | |
targetGroupRequest = without_service_token(event['ResourceProperties']) | |
del targetGroupRequest['TargetGroupAttributes'] | |
# fix request payload | |
# boto3 expects int but cfn request has converted to str | |
convertToInt('HealthCheckIntervalSeconds', targetGroupRequest) | |
convertToInt('HealthCheckTimeoutSeconds', targetGroupRequest) | |
convertToInt('Port', targetGroupRequest) | |
# max 32 characters | |
targetGroupRequest['Name'] = generateName(targetGroupRequest['Name']) | |
# default to HTTP2, so that it can be overridden to gRPC | |
if 'ProtocolVersion' not in targetGroupRequest: | |
targetGroupRequest['ProtocolVersion'] = 'HTTP2' | |
logger.info('Creating target group') | |
logger.info(targetGroupRequest) | |
targetGroupResponse = elb.create_target_group(**targetGroupRequest) | |
logger.info(targetGroupResponse) | |
arn = targetGroupResponse['TargetGroups'][0]['TargetGroupArn'] | |
attributesRequest = { | |
'TargetGroupArn': arn, | |
'Attributes': request['TargetGroupAttributes'] | |
} | |
logger.info('Setting target group attributes') | |
logger.info(attributesRequest) | |
attributesResponse = elb.modify_target_group_attributes( | |
**attributesRequest) | |
logger.info(attributesResponse) | |
return targetGroupResponse['TargetGroups'][0]['TargetGroupArn'] | |
@helper.delete | |
def delete(event, context): | |
try: | |
logger.info('Delete target group {}'.format( | |
event['PhysicalResourceId'])) | |
elb.delete_target_group(TargetGroupArn=event['PhysicalResourceId']) | |
except Exception as e: | |
logging.critical(e, exc_info=True) | |
pass | |
return | |
def handler(event, context): | |
helper(event, context) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: 2010-09-09 | |
Description: 'ECS Fargate deployment and dependant resources' | |
Parameters: | |
Name: | |
Description: Name | |
Type: String | |
VpcId: | |
Description: VPC Id | |
Type: AWS::EC2::VPC::Id | |
ServicePort: | |
Type: String | |
Description: The port of the ECS Service | |
Resources: | |
Http2LoadBalancerTargetGroup: | |
Type: Custom::Http2TargetGroup | |
Properties: | |
ServiceToken: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:cfn-http2-target-group | |
Name: !Sub ${Name}-tg | |
VpcId: !Ref VpcId | |
Protocol: HTTP | |
Port: !Ref ServicePort | |
TargetType: ip | |
TargetGroupAttributes: | |
- Key: deregistration_delay.timeout_seconds | |
Value: '5' | |
- Key: stickiness.enabled | |
Value: 'true' | |
- Key: stickiness.type | |
Value: lb_cookie | |
- Key: stickiness.lb_cookie.duration_seconds | |
Value: '86400' #1 day | |
HealthCheckIntervalSeconds: 300 | |
HealthCheckTimeoutSeconds: 30 | |
HealthCheckPath: !Sub /health | |
HealthCheckProtocol: HTTP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment