【问题标题】:Create A record in CloudFormation for EMR master node private IP address在 CloudFormation 中为 EMR 主节点私有 IP 地址创建一条记录
【发布时间】:2019-03-27 20:07:55
【问题描述】:

我想知道是否有办法在 CloudFormation 配置中声明 AWS::Route53::RecordSet,该配置指向 EMR 集群上主节点的私有 IP 地址,该地址也在相同配置中定义?

CloudFormation 脚本应该是不言自明的:

  rVPC:
    Type: AWS::EC2::VPC
    # ... 

  rMyEMRCluster:
    Type: AWS::EMR::Cluster
    # ...

  rPrivateHostedZone:
    Type: AWS::Route53::HostedZone
    Properties:
      Name: "example.com"
      VPCs:
        - VPCId: !Ref rVPC
          VPCRegion: ${AWS::Region}

  rMyRecordSet:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId: !Ref rPrivateHostedZone
      Name: !Sub "sub.example.com"
      Region: ${AWS::Region}
      Type: A
      ResourceRecords:
        # TODO: How can I do something like this:
        # - GetAtt rMyEMRCluster.MasterNodePrivateIpAddress

【问题讨论】:

    标签: amazon-web-services amazon-cloudformation amazon-emr amazon-route53


    【解决方案1】:

    不完全是。

    唯一可用的返回值是MasterPublicDNS。但是,这应该解析为主节点的 IP 地址。

    请参阅AWS::EMR::Cluster - AWS CloudFormation返回值部分。

    【讨论】:

    • 这行不通,因为 route53 不会接受不是 ipv4 的值。
    【解决方案2】:

    如果您的本地网络可以解析 MasterPublicDNS。大多数情况下不是。所以你必须将 MasterPublicDNS 转换为 IP 地址,你可以像下面那样做

    #ResourceRecords: # - !GetAtt rMyEMRCluster.MasterPublicDNS # convert ip-10-11-12-13.ec2.internal to 10.11.12.13 ResourceRecords: - !Join - '.' - - !Select - 1 - !Split - "-" - !Select [0, !Split [".ec2.internal", !GetAtt rMyEMRCluster.MasterPublicDNS]] - !Select - 2 - !Split - "-" - !Select [0, !Split [".ec2.internal", !GetAtt rMyEMRCluster.MasterPublicDNS]] - !Select - 3 - !Split - "-" - !Select [0, !Split [".ec2.internal", !GetAtt rMyEMRCluster.MasterPublicDNS]] - !Select - 4 - !Split - "-" - !Select [0, !Split [".ec2.internal", !GetAtt rMyEMRCluster.MasterPublicDNS]]

    【讨论】:

      【解决方案3】:

      您可以尝试为此使用自定义资源。它可以使用emr:ListInstances 获取 IP,然后您可以在 Route 53 资源中使用该结果。

      我还没有尝试过,但是类似下面的方法应该可以。如果 EMR 需要一段时间来创建主节点并且 CloudFormation 还没有等待,您可能需要在其中添加一些延迟。

      Resources:
        DescribeClusterRole:
          Type: AWS::IAM::Role
          Properties:
            AssumeRolePolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Action: sts:AssumeRole
                  Effect: Allow
                  Principal:
                    Service: lambda.amazonaws.com
            ManagedPolicyArns:
              - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
            Policies:
              - PolicyName: DescribeCluster
                PolicyDocument:
                  Version: '2012-10-17'
                  Statement:
                    - Action: elasticmapreduce:ListInstances
                      Effect: Allow
                      Resource: "*"
        GetClusterPrivateIP:
          Type: AWS::Lambda::Function
          Properties:
            Runtime: python3.6
            Handler: index.handler
            Role: !Sub ${DescribeClusterRole.Arn}
            Timeout: 60
            Code:
              ZipFile: |
                import boto3
                import cfnresponse
                import traceback
      
                def handler(event, context):
                  try:
                    response = boto3.client('emr').list_instances(
                        ClusterId=event['ResourceProperties']['ClusterId'],
                        InstanceGroupTypes=['MASTER'],
                    )
      
                    ip = response['Instances'][0]['PrivateIpAddress']
      
                    cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, ip)
                  except:
                    traceback.print_last()
                    cfnresponse.send(event, context, cfnresponse.FAIL, {}, "ok")
        MasterIp:
          Type: Custom::EmrMasterIp
          Properties:
            ServiceToken: !Sub ${GetClusterPrivateIP.Arn}
            ClusterId: !Ref rMyEMRCluster
        rMyRecordSet:
          Type: AWS::Route53::RecordSet
          Properties:
            HostedZoneId: !Ref rPrivateHostedZone
            Name: !Sub "sub.example.com"
            Region: ${AWS::Region}
            Type: A
            ResourceRecords:
              !Ref MasterIp
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-24
        相关资源
        最近更新 更多