【问题标题】:Auto-assign IPv6 address via AWS and CloudFormation通过 AWS 和 CloudFormation 自动分配 IPv6 地址
【发布时间】:2017-06-22 04:07:50
【问题描述】:

有没有办法在自动扩展组+启动配置中将 IPv6 地址自动分配给 EC2 实例?

VPC 和子网均针对 IPv6 设置。手动创建的实例是可以的。 我也可以手动分配它们,但我似乎无法在 CloudFormation 中找到方法。

【问题讨论】:

    标签: amazon-ec2 ipv6 amazon-cloudformation


    【解决方案1】:

    目前的状态是 CloudFormation 对 IPv6 的支持是可行的。不好玩也不完整,但你可以用它构建一个堆栈——我不得不使用 2 个自定义资源:

    • 第一个是通用资源,我用于其他用途并在此处重复使用,以解决缺少的功能,以从 VPC 的 /56 自动提供的网络构建子网 /64 CIDR 块
    • 另一个我必须专门添加以解决 CloudFormation 正确使用的 EC2 API 中的错误。

    这是我的设置:

    1。将 IPv6 CIDR 块添加到您的 VPC:

    VPCipv6:
      Type: "AWS::EC2::VPCCidrBlock"
      Properties:
        VpcId: !Ref VPC
        AmazonProvidedIpv6CidrBlock: true
    

    2。提取用于创建 /64 子网的网络前缀:

    As explained in this answer.

    VPCipv6Prefix:
      Type: Custom::Variable
      Properties:
        ServiceToken: !GetAtt [ IdentityFunc, Arn ]
        Value: !Select [ 0, !Split [ "00::/", !Select [ 0, !GetAtt VPC.Ipv6CidrBlocks ] ] ]
    

    IdentityFunc 是在 Lambda 中为“自定义变量”实现的“身份函数”,as described in this answer。与此链接的答案不同,我直接在同一个堆栈中实现该函数,因此更易于维护。 See here for the gist.

    3。将 IPv6 默认路由添加到您的互联网网关:

    RouteInternet6:
      Type: "AWS::EC2::Route"
      Properties:
        RouteTableId: !Ref RouteTableMain
        DestinationIpv6CidrBlock: "::/0"
        GatewayId: !Ref IGWPublicNet
      DependsOn:
        - IGWNetAttachment
    

    IGWNetAttachment 是对堆栈中定义的AWS::EC2::VPCGatewayAttachment 的引用。如果不等待,可能无法正确设置路由

    4。将 IPv6 CIDR 块添加到您的子网:

    SubnetA:
      Type: AWS::EC2::Subnet
      Properties:
        AvailabilityZone: !Select [ 0, !GetAZs { Ref: "AWS::Region" } ]
        CidrBlock: 172.20.0.0/24
        MapPublicIpOnLaunch: true
        # The following does not work if MapPublicIpOnLaunch because of EC2 bug
        ## AssignIpv6AddressOnCreation: true 
        Ipv6CidrBlock: !Sub "${VPCipv6Prefix.Value}00::/64"
        VpcId:
          Ref: VPC
    

    关于 AssignIpv6AddressOnCreation 被注释掉 - 这通常是您想要做的,但显然,EC2 API 中有一个错误阻止它工作 - 这不是 CloudFormation 的错误。这在this AWS forums thread 中进行了记录,以及我接下来将在此处介绍的解决方案。

    5。用另一个 lambda 修复 AssignIpv6AddressOnCreation 问题:

    这是 lambda 设置:

    IPv6WorkaroundRole:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Principal:
              Service:
              - lambda.amazonaws.com
            Action:
            - sts:AssumeRole
        Path: "/"
        Policies:
          - PolicyName: !Sub "ipv6-fix-logs-${AWS::StackName}"
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
              - Effect: Allow
                Action:
                - logs:CreateLogGroup
                - logs:CreateLogStream
                - logs:PutLogEvents
                Resource: arn:aws:logs:*:*:*
          - PolicyName: !Sub "ipv6-fix-modify-${AWS::StackName}"
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
              - Effect: Allow
                Action:
                - ec2:ModifySubnetAttribute
                Resource: "*"
    
    IPv6WorkaroundLambda:
      Type: AWS::Lambda::Function
      Properties:
        Handler: "index.lambda_handler"
        Code: #import cfnresponse below required to send respose back to CFN
          ZipFile:
            Fn::Sub: |
              import cfnresponse
              import boto3
    
              def lambda_handler(event, context):
                  if event['RequestType'] is 'Delete':
                    cfnresponse.send(event, context, cfnresponse.SUCCESS)
                    return
    
                  responseValue = event['ResourceProperties']['SubnetId']
                  ec2 = boto3.client('ec2', region_name='${AWS::Region}')
                  ec2.modify_subnet_attribute(AssignIpv6AddressOnCreation={
                                                  'Value': True
                                                },
                                                SubnetId=responseValue)
                  responseData = {}
                  responseData['SubnetId'] = responseValue
                  cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
        Runtime: python2.7
        Role: !GetAtt IPv6WorkaroundRole.Arn
        Timeout: 30
    

    这就是你使用它的方式:

    IPv6WorkaroundSubnetA:
      Type: Custom::SubnetModify
      Properties:
        ServiceToken: !GetAtt IPv6WorkaroundLambda.Arn
        SubnetId: !Ref SubnetA
    

    此调用与自动缩放组竞争以完成设置,但它不太可能失败 - 我运行了几十次,在第一个实例启动之前正确设置字段从来没有问题。

    【讨论】:

    • 感谢@Guss。我仍然认为这是 2020 年底的问题。
    【解决方案2】:

    我遇到了一个非常相似的问题,并就此与 AWS Support 进行了交谈。当前状态是 CloudFormation 对 IPv6 的支持非常有限。

    我们最终为许多特定于 IPv6 的事物创建了自定义资源。我们有一个自定义资源:

    • 在子网上启用 IPv6 分配
    • 创建仅出口 Internet 网关
    • 添加到仅出口 Internet 网关的路由(内置 Route 资源指出它在指向 EIGW 时“无法稳定”)

    自定义资源只是执行“原始”API 调用的 Lambda 函数,以及授予 Lambda 执行该 API 调用足够权限的 IAM 角色。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      相关资源
      最近更新 更多