如何在CloudFormation中使用Opsworks Stack注册ECS群集?

时间:2015-08-23 17:45:32

标签: aws-opsworks amazon-cloudformation amazon-ecs

我无法弄清楚如何在CloudFormation中使用ECS群集设置OpsWorks层。由于下面的错误,我的图层创建失败,但似乎没有一种明确的方法来在模板中注册具有堆栈的集群。我尝试将2015-08-23 17:32:05,401 2249 DEBUG ? openerp.service.server: Debug message 添加到Stack和Layer,但这不起作用。 API有一个命令,但我想在模板中包含所有内容。

错误:

EcsClusterArn

模板片段:

Attributes - EcsClusterArn: XXX must be registered to the layer's stack first.

谢谢, 噻吩

3 个答案:

答案 0 :(得分:2)

我的印象是群集到堆栈的注册失败。为了解决这个问题,我已经实现了一个lambda函数来手动进行注册。我在github上发布了一个示例模板:https://github.com/arjenderijke/aws-cloud-examples/blob/master/cloudformation/opsworks/opsworks-ecs-layer.template

cloudformation模板包含一个opsworks堆栈的完整示例,其中包含ecs层和其他最少的必需资源。堆栈通常无法创建,因为ecs群集不会自动注册。为解决此问题,模板实现了一个运行aws lambda函数的自定义资源。此函数将群集注册到堆栈。通过使用此自定义资源,不再出现错误。

 "OpsworksRegisterCluster": {
  "Type": "AWS::Lambda::Function",
  "Properties": {
    "Handler": "index.lambda_handler",
    "Role": { "Fn::GetAtt" : ["LambdaExecutionRole", "Arn"] },
    "Code": {
      "ZipFile":  { "Fn::Join": ["\n", [
        "import boto3",
        "import json",
        "import cfnresponse",
        "ecsclient = boto3.client('ecs')",
        "opsworksclient = boto3.client('opsworks',",
        "  region_name='us-east-1',",
        "  endpoint_url='https://opsworks.us-east-1.amazonaws.com')",
        "def lambda_handler(event, context):",
        "  try:",
        "    if (event['RequestType'] == 'Create'):",
        "      ecscluster = ecsclient.describe_clusters(clusters=[",
        "        event['ResourceProperties']['EcsClusterName']])",
        "      response = opsworksclient.register_ecs_cluster(",
        "        EcsClusterArn=ecscluster['clusters'][0]['clusterArn'],",
        "        StackId=event['ResourceProperties']['OpsworksStackId']",
        "      )",
        "      responseData = {}",
        "      responseData['data'] = response['EcsClusterArn']",
        "      cfnresponse.send(event, context, cfnresponse.SUCCESS,   responseData, \"CustomResourcePhysicalID\")",
        "    else:",
        "      responseData = {}",
        "      cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, \"CustomResourcePhysicalID\")",
        "  except Exception as e:",
        "    responseData = {}",
        "    responseData['error'] = e.message",
        "    cfnresponse.send(event, context, cfnresponse.FAILED, responseData, \"CustomResourcePhysicalID\")"
      ]]}
    },
    "Runtime": "python2.7",
    "Timeout": "10"
  }
},

答案 1 :(得分:1)

仅仅为了每个人的知识,几天前我在AWS云计算中遇到了这个问题,我就此向亚马逊提出了一个案例。

看来这个问题仍然存在于他们的API中(正如Thien在评论中指出这个bug应该在2016年2月解决)并且它还没有得到解决,不确定是因为我使用的是嵌套堆叠存在这个问题(可能在单个模板中并非如此,我还没试过)。

AWS人员要求我使用lambda函数来解决此问题,它与上面的@Arjen提供的lambda函数非常相似。因此,如果您遇到此问题,请使用上面提供的lambda函数。

谢谢, 和Manish

答案 2 :(得分:0)

根据Adding an ECS Cluster Layer to a Stack部分,将群集与堆栈相关联需要两个操作

  

[...]使用堆栈注册集群,然后创建关联的层。 AWS OpsWorks控制台结合了以下步骤;图层创建会自动注册指定的集群。 如果您使用AWS OpsWorks API,CLI或SDK,则必须使用单独的操作来注册群集并创建关联的层 [强调我的]

您声明您尝试将EcsClusterArn添加到堆栈和图层但不起作用,但错误消息确认Amazon ECS群集必须是首先注册到图层的堆栈,您的示例模板实际上缺少这个方面?如果您可能只需要重复您的resp。来自AWS::OpsWorks::Layer内的AWS::OpsWorks::Stack的片段:

   "Attributes" : {
      "EcsClusterArn" : {
        "Fn::Join" : [ "", [ "arn:aws:ecs:", {
          "Ref" : "AWS::Region"
        }, ":", {
          "Ref" : "AWS::AccountId"
        }, ":cluster/", {
          "Ref" : "ecsCluster"
        } ] ]
      }
    },