Amazon ec2 通过AWS和CloudFormation自动分配IPv6地址

Amazon ec2 通过AWS和CloudFormation自动分配IPv6地址,amazon-ec2,ipv6,amazon-cloudformation,Amazon Ec2,Ipv6,Amazon Cloudformation,在自动缩放组+启动配置中,是否有办法将IPv6地址自动分配给EC2实例 VPC和子网都是为IPv6设置的。手动创建的实例没有问题。 我也可以手动分配它们,但我似乎找不到在CloudFormation中进行分配的方法。我遇到了一个非常类似的问题,并就此与AWS支持人员进行了交谈。目前的情况是,云信息中对IPv6的支持非常有限 我们最终为许多特定于IPv6的东西创建了自定义资源。我们有一个自定义资源: 在子网上启用IPv6分配 创建仅出口的Internet网关 将路由添加到仅出口的Internet

在自动缩放组+启动配置中,是否有办法将IPv6地址自动分配给EC2实例

VPC和子网都是为IPv6设置的。手动创建的实例没有问题。
我也可以手动分配它们,但我似乎找不到在CloudFormation中进行分配的方法。

我遇到了一个非常类似的问题,并就此与AWS支持人员进行了交谈。目前的情况是,云信息中对IPv6的支持非常有限

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

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

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

当前状态是对IPv6的CloudFormation支持是可行的。这既不有趣也不完整,但您可以使用它构建一个堆栈-我必须使用2个自定义资源:

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

1.将IPv6 CIDR块添加到您的VPC: 2.提取用于创建/64子网的网络前缀:

IdentityFunc
是在Lambda中为“自定义变量”实现的“标识函数”。与此链接答案不同,我直接在同一堆栈中实现该函数,因此更易于维护

3.将IPv6默认路由添加到internet网关:
igwnetachment
是对堆栈中定义的
AWS::EC2::VPCGatewayAttachment
的引用。如果不等待,路线可能无法正确设置

4.将IPv6 CIDR块添加到子网: 关于被注释掉的
AssignIpv6AddressOnCreation
,这通常是您想要做的,但是显然,EC2 API中有一个bug阻止了它的工作,这并不是因为CloudFormation的错误。这一点在中有记录,以及我将在下面介绍的解决方案

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年底的一个问题。
RouteInternet6:
  Type: "AWS::EC2::Route"
  Properties:
    RouteTableId: !Ref RouteTableMain
    DestinationIpv6CidrBlock: "::/0"
    GatewayId: !Ref IGWPublicNet
  DependsOn:
    - IGWNetAttachment
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
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