在CloudFormation中为EMR主节点专用IP地址创建记录

问题描述 投票:0回答:2

我想知道是否有办法在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
2个回答
1
投票

不完全的。

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

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


0
投票

您可以尝试使用自定义资源。它可以使用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
© www.soinside.com 2019 - 2024. All rights reserved.