开发者社区> 问答> 正文

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

宋淑婷 2019-04-23 13:31:29 429

我想知道是否有办法AWS::Route53::RecordSet在CloudFormation配置中声明一个指向同一配置中定义的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
分享到
取消 提交回答
全部回答(1)
  • 宋淑婷
    2019-07-17 23:34:03

    您可以尝试使用自定义资源。它可以使用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
    

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

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

    0 0
+ 订阅

时时分享云计算技术内容,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

推荐文章