Como adiciono rotas à tabela de rotas principal na minha VPC com o CloudFormation?
Quero adicionar rotas à tabela de rotas principal ao criar minha Amazon Virtual Private Cloud (Amazon VPC) no AWS CloudFormation.
Breve descrição
Quando você usa o CloudFormation para criar um Amazon VPC, o CloudFormation não reconhece a tabela de rotas principal que é criada por padrão. Portanto, as informações sobre a tabela de rotas não podem ser passadas entre o Amazon VPC e o CloudFormation. Como resultado, você não pode adicionar ou remover rotas da tabela de rotas principal porque não pode referenciar a tabela de rotas do seu modelo do CloudFormation.
Resolução
Observação: se você receber erros ao executar comandos da AWS Command Line Interface (AWS CLI), verifique se está usando a versão mais recente da AWS CLI.
Para resolver esse problema, você pode usar um recurso personalizado baseado no AWS Lambda no modelo do CloudFormation. A pilha do CloudFormation cria um Amazon VPC. Em seguida, o recurso personalizado usa uma função do AWS Lambda para recuperar o ID da tabela de rotas principal que está associado à sua Amazon VPC.
Crie uma pilha do CloudFormation usando o seguinte modelo 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
Os dados que o recurso personalizado retorna contêm o ID da tabela de rotas principal. Você pode referenciar o ID usando GetAtt no AWS::EC2::Route para adicionar rotas à tabela de rotas principal. Além disso, as saídas da pilha exibem o ID da tabela de rotas.
Veja a seguir um exemplo do corpo de resposta SUCCESS que o recurso personalizado envia para a pilha do 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:XXXX:stack/VPC-RT/06c957b0-297e-11ed-afb5-02ca6fd67f8d", "RequestId": "55c0f2b8-3044-47f7-aba4-84502b4ef632", "LogicalResourceId": "Lambdatrigger", "NoEcho": false, "Data": { "RouteTableID": "rtb-0fba8d15701234567a" } }
Conteúdo relevante
- AWS OFICIALAtualizada há um ano
- AWS OFICIALAtualizada há 4 anos
- AWS OFICIALAtualizada há um ano