0

我正在尝试在 Cloudformation 模板中创建 AWS 自定义资源以检索 MSK 代理 DNS 详细信息。

下面是我的示例 lambda 代码:

import json
import logging
import boto3
import subprocess
import shlex
import os
import time
from hashlib import md5
from crhelper import CfnResource
from time import sleep

logger = logging.getLogger(__name__)
helper = CfnResource(json_logging=True, log_level='DEBUG')




@helper.create
@helper.update
def create_handler(event, _):
    print('Received event: %s' % json.dumps(event))
    retry_timeout = 0
    if "Timeout" in event['ResourceProperties']:
        retry_timeout = int(event['ResourceProperties']["Timeout"])
    if retry_timeout > 600:
        retry_timeout = 600
    MskArn = event['ResourceProperties']['MskArn']
    kafkaClient = boto3.client('kafka', region_name=event['ResourceProperties']['aws-region'])
    while True:
        try:
            response = kafkaClient.list_nodes(
                ClusterArn=event['ResourceProperties']['MskArn']
            )
            r1=response['NodeInfoList']
            BrokerCount=len(r1)
            i = 0
            DNS=[]
            name = event['ResourceProperties']['Name']
            while i < BrokerCount:
                broker=response['NodeInfoList'][i]
                brokerDNS=broker['BrokerNodeInfo']['Endpoints'][0]
                DNS.append(brokerDNS)
                print(brokerDNS)
                i = i + 1
            return DNS
            outp = DNS
            break
        except Exception as e:
            if retry_timeout < 1:
                raise
            else:
                logging.error('Exception: %s' % e, exc_info=True)
                print("retrying until timeout...")
                time.sleep(5)
                retry_timeout = retry_timeout - 5
    response_data = {}
    if "ResponseKey" in event['ResourceProperties']:
        response_data[event['ResourceProperties']["ResponseKey"]] = outp
    if len(outp.encode('utf-8')) > 1000:
        outp = 'MD5-' + str(md5(outp.encode('utf-8')).hexdigest())
    helper.Data.update(response_data)
    return outp


def lambda_handler(event, context):
    helper(event, context)
    print(response_data)

下面是我的示例 AWS Cloudformation 模板:

---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'To Get MSK Broker DNS CloudFormation Template'
Resources:
  GetMskBrokersDetails:
    Type: "Custom::GetMskDetails"
    Version: '1.0'
    Properties:
      Name: GetMskBrokerDNS
      ServiceToken: LAMBDA_ARN
      aws-region: !Sub "${AWS::Region}"
      MskArn: MSK_CLUSTER_ARN

Outputs:
  MskBrokerDns1:
    Description: Msk Broker DNS Records
    Value: !Ref GetMskBrokersDetails

以上工作正常。当我执行上述模板时,它会给我以下输出。

MskBrokerDns1   ['b-1.kafka.ap-south-1.amazonaws.com', 'b-2.kafka.ap-south-1.amazonaws.com']

由于上面的输出是列表,我们希望在两个单独的输出变量中获得上面的 DNS 详细信息。如下所示:

Outputs:
  MskBrokerDns1:
    Description: Msk Broker DNS Records
    Value: !Select [ 0, !Ref GetMskBrokersDetails ]
  MskBrokerDns2:
    Description: Msk Broker DNS Records
    Value: !Select [ 1, !Ref GetMskBrokersDetails ]

当我们尝试执行具有上述更改的模板时,我们得到以下错误:

模板错误:Fn::Select 需要一个包含两个元素的列表参数:一个整数索引和一个列表

因此,我们请求社区支持,我们如何解决上述问题。

4

1 回答 1

0

经过一番打击和试验,我们能够得到我们想要的回应。这可能不是有效的方法。拉姆达代码:

import json
import logging
import boto3
import subprocess
import shlex
import os
import time
from hashlib import md5
from crhelper import CfnResource
from time import sleep

logger = logging.getLogger(__name__)
helper = CfnResource(json_logging=True, log_level='DEBUG')




@helper.create
@helper.update
def create_handler(event, _):
    print('Received event: %s' % json.dumps(event))
    retry_timeout = 0
    if "Timeout" in event['ResourceProperties']:
        retry_timeout = int(event['ResourceProperties']["Timeout"])
    if retry_timeout > 600:
        retry_timeout = 600
    MskArn = event['ResourceProperties']['MskArn']
    kafkaClient = boto3.client('kafka', region_name=event['ResourceProperties']['aws-region'])
    while True:
        try:
            response = kafkaClient.list_nodes(
                ClusterArn=event['ResourceProperties']['MskArn']
            )
            r1=response['NodeInfoList']
            BrokerCount=len(r1)
            i = 0
            DNS=[]
            name = event['ResourceProperties']['Name']
            while i < BrokerCount:
                broker=response['NodeInfoList'][i]
                brokerDNS=broker['BrokerNodeInfo']['Endpoints'][0]
                DNS.append(brokerDNS)
                i = i + 1
            outp = DNS
            break
        except Exception as e:
            if retry_timeout < 1:
                raise
            else:
                logging.error('Exception: %s' % e, exc_info=True)
                print("retrying until timeout...")
                time.sleep(5)
                retry_timeout = retry_timeout - 5
    response_data = {}
    response_data['BrokerDNS1'] = DNS[0]
    response_data['BrokerDNS2'] = DNS[1]
    print(response_data)
    helper.Data.update(response_data)

def lambda_handler(event, context):
    helper(event, context)

以下是 AWS Cloudformation 资源定义:

  GetMskBrokersDetails:
    Type: "Custom::GetMskDetails"
    Version: '1.0'
    Properties:
      Name: GetMskBrokerDNS
      ServiceToken: !Ref MskGetBrokerDnsLambdaArn
      aws-region: !Sub "${AWS::Region}"
      MskArn: !Ref MskCluster
Outputs:
  MskBrokerDns1:
    Description: Msk Broker DNS Records
    Value: !GetAtt GetMskBrokersDetails.BrokerDNS1
  MskBrokerDns2:
    Description: Msk Broker DNS Records
    Value: !GetAtt GetMskBrokersDetails.BrokerDNS2
于 2020-03-14T18:59:28.493 回答