¿Cómo añado rutas a la tabla de enrutamiento principal de mi Amazon VPC con CloudFormation?
Quiero añadir rutas a la tabla de enrutamiento principal al crear mi Amazon Virtual Private Cloud (Amazon VPC) en AWS CloudFormation.
Resolución
Cuando usa CloudFormation para crear una Amazon VPC, CloudFormation no reconoce la tabla de enrutamiento principal que se crea de forma predeterminada. No puede añadir ni eliminar rutas de la tabla de rutas principal porque no puede hacer referencia a la tabla de enrutamiento de su plantilla de CloudFormation.
Para resolver este problema, puede utilizar un recurso personalizado y respaldado por AWS Lambda en la plantilla de CloudFormation.
Para crear una pila de CloudFormation con un recurso personalizado, utilice la siguiente plantilla RouteTable-template.yml:
AWSTemplateFormatVersion: 2010-09-09 Description: Template to add routes to default/main routetable of VPC Resources: MyVPC: Type: 'AWS::EC2::VPC' Properties: CidrBlock: 10.0.0.0/16 Tags: - Key: Env Value: Test LambdaIAMRole: Type: 'AWS::IAM::Role' DependsOn: MyVPC Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: root PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'ec2:Describe*' Resource: '*' - Effect: Allow Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: 'arn:aws:logs:*:*:*' LambdaFunction: Type: 'AWS::Lambda::Function' Properties: Handler: index.lambda_handler Role: !GetAtt LambdaIAMRole.Arn Runtime: python3.9 Timeout: 50 Code: ZipFile: | from __future__ import print_function import json import boto3 import urllib3 import cfnresponse SUCCESS = "SUCCESS" FAILED = "FAILED" http = urllib3.PoolManager() print('Loading function') ec2 = boto3.client('ec2') def lambda_handler(event, context): print("Received event: " + json.dumps(event, indent=2)) responseData={} try: if event['RequestType'] == 'Delete': print("Request Type:",event['RequestType']) print("Delete Request - No Physical resources to delete") elif event['RequestType'] == 'Create': print("Request Type:",event['RequestType']) VPCID=event['ResourceProperties']['VPCID'] RouteTableID=get_vpc(VPCID) responseData={'RouteTableID':RouteTableID} print("Sending response to custom resource") elif event['RequestType'] == 'Update': print("Request Type:",event['RequestType']) VPCID=event['ResourceProperties']['VPCID'] RouteTableID=get_vpc(VPCID) responseData={'RouteTableID':RouteTableID} print("Sending response to custom resource") responseStatus = 'SUCCESS' print("responseStatus: " + responseStatus) cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID") except Exception as e: print('Failed to process:', e) responseStatus = 'FAILURE' responseData = {'Failure': 'Something bad happened.'} cfnresponse.send(event, context, cfnresponse.FAILURE, responseData, "CustomResourcePhysicalID") def get_vpc(VPCID): response = ec2.describe_route_tables ( Filters=[ { 'Name': 'association.main', 'Values': [ 'true' ] }, { 'Name': 'vpc-id', 'Values': [ VPCID ] } ] ) print("Printing the VPC Route Table ID ....") RouteTableID=response['RouteTables'][0]['RouteTableId'] print(RouteTableID) return RouteTableID def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False): responseUrl = event['ResponseURL'] print(responseUrl) responseBody = {'Status': responseStatus, 'Reason': 'See the details in CloudWatch Log Stream: ' + context.log_stream_name, 'PhysicalResourceId': physicalResourceId or context.log_stream_name, 'StackId': event['StackId'], 'RequestId': event['RequestId'], 'LogicalResourceId': event['LogicalResourceId'], 'Data': responseData} json_responseBody = json.dumps(responseBody) print("Response body:\n" + json_responseBody) headers = { 'content-type' : '', 'content-length' : str(len(json_responseBody)) } try: response = http.request('PUT', responseUrl, headers=headers, body=json_responseBody) print("Status code: " + response.reason) except Exception as e: print("send(..) failed executing requests.put(..): " + str(e)) Lambdatrigger: Type: 'Custom::RouteTableLambda' Properties: ServiceToken: !GetAtt LambdaFunction.Arn VPCID: !Ref MyVPC MyInternetGateway: Type: 'AWS::EC2::InternetGateway' Properties: Tags: - Key: Env Value: Test AttachGateway: Type: 'AWS::EC2::VPCGatewayAttachment' Properties: VpcId: !Ref MyVPC InternetGatewayId: !Ref MyInternetGateway MyRoute: Type: 'AWS::EC2::Route' Properties: RouteTableId: !GetAtt Lambdatrigger.RouteTableID DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyInternetGateway Outputs: RouteTableID: Value: !GetAtt Lambdatrigger.RouteTableID
El recurso personalizado usa una función de Lambda para recuperar el ID de la tabla de enrutamiento principal. Para hacer referencia al ID, utilice la función GetAtt en AWS::EC2::Route para añadir rutas a la tabla de enrutamiento principal. O bien, abra la consola de CloudFormation, a continuación, seleccione Salida. Puede encontrar la información en RouteTableID.
En el siguiente ejemplo se muestra el cuerpo de la respuesta SUCCESS que el recurso personalizado envía a la pila de CloudFormation:
{ "Status": "SUCCESS", "Reason": "See the details in CloudWatch Log Stream: 2022/08/31/[$LATEST]c48b90efb3944c11ad3fb6e1ce5e1f45", "PhysicalResourceId": "CustomResourcePhysicalID", "StackId": "arn:aws:cloudformation:us-west-1:abcd:stack/VPC-RT/06c957b0-297e-11ed-afb5-02ca6fd67f8d", "RequestId": "55c0f2b8-3044-47f7-aba4-84502b4ef632", "LogicalResourceId": "Lambdatrigger", "NoEcho": false, "Data": { "RouteTableID": "rtb-0fba8d15701234567a" } }
Contenido relevante
- OFICIAL DE AWSActualizada hace 2 meses
- OFICIAL DE AWSActualizada hace 3 años
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace 3 años