如何在 CloudFormation 中向 Opsworks Stack 注册 ECS 集群?
Posted
技术标签:
【中文标题】如何在 CloudFormation 中向 Opsworks Stack 注册 ECS 集群?【英文标题】:How to register ECS Cluster with Opsworks Stack in CloudFormation? 【发布时间】:2015-11-17 03:03:08 【问题描述】:我不知道如何在 CloudFormation 中使用 ECS 集群设置 OpsWorks 层。由于以下错误,我的图层创建失败,但似乎没有一种明确的方法可以将集群注册到模板中的堆栈。我尝试将EcsClusterArn
添加到堆栈和层,但没有奏效。 API 有一个命令,但我想在我的模板中包含所有内容。
错误:
Attributes - EcsClusterArn: XXX must be registered to the layer's stack first.
模板片段:
"ecsCluster" :
"Type" : "AWS::ECS::Cluster"
,
...
"opsworksStack" :
"Type" : "AWS::OpsWorks::Stack",
"Properties" :
"Name" : "my-stack",
"ServiceRoleArn" :
"Fn::Join" : [ "", [ "arn:aws:iam::",
"Ref" : "AWS::AccountId"
, ":role/",
"Ref" : "ServiceRole"
] ]
,
"DefaultInstanceProfileArn" :
"Fn::Join" : [ "", [ "arn:aws:iam::",
"Ref" : "AWS::AccountId"
, ":instance-profile/",
"Ref" : "InstanceRole"
] ]
,
"UseOpsworksSecurityGroups" : "false",
"ChefConfiguration" :
"BerkshelfVersion" : "3.3.0",
"ManageBerkshelf" : "true"
,
"ConfigurationManager" :
"Name" : "Chef",
"Version" : "11.10"
,
"opsworksLayer" :
"Type" : "AWS::OpsWorks::Layer",
"DependsOn" : "ecsCluster",
"Properties" :
"StackId" :
"Ref" : "opsworksStack"
,
"Type" : "ecs-cluster",
"Name" : "my-layer",
"Shortname" : "my-layer",
"Attributes" :
"EcsClusterArn" :
"Fn::Join" : [ "", [ "arn:aws:ecs:",
"Ref" : "AWS::Region"
, ":",
"Ref" : "AWS::AccountId"
, ":cluster/",
"Ref" : "ecsCluster"
] ]
,
"CustomSecurityGroupIds" : [
"Ref" : "ec2DefaultSecurityGroup"
],
"EnableAutoHealing" : "true",
"AutoAssignElasticIps" : "false",
"AutoAssignPublicIps" : "false",
"InstallUpdatesOnBoot" : "true"
谢谢, 天
【问题讨论】:
您好 Thien,我只是想知道您是否能够解决此问题?在将 ECS 集群附加到 Opsworks 堆栈时,我也面临同样的错误。 @ManishJoshi 我在 Amazon 创建了一个案例,他们已于 2016 年 2 月 24 日解决了该错误。它现在应该可以在 OpsWorks 层的“属性”部分中使用“EcsClusterArn”,如所述在文档中。 谢谢@Thien,不幸的是它仍然不适合我,我已经向亚马逊提出了案例,他们仍在调查中。如果我也发现此错误的其他原因,我会告诉这里的人:) 【参考方案1】:我的印象是集群注册到栈失败。为了解决这个问题,我实现了一个 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"
,
【讨论】:
【参考方案2】:据大家所知,几天前我在使用 AWS cloudformation 时遇到了这个问题,为此我向 Amazon 提出了一个案例。
似乎这个问题仍然存在于他们的 API 中(正如 Thien 在 cmets 中指出的那样,这个 bug 应该在 2016 年 2 月解决)并且尚未解决,不确定是因为我使用的是嵌套堆栈存在这个问题(可能在单个模板中不是这样,我没试过)。
AWS 人员要求我使用 lambda 函数来解决此问题,它与上面 @Arjen 提供的 lambda 函数非常相似。所以如果你遇到这个问题,请使用上面提供的 lambda 函数。
谢谢, 马尼什
【讨论】:
【参考方案3】:根据Adding an ECS Cluster Layer to a Stack 部分,将集群与堆栈关联需要两个操作:
[...] 向堆栈注册集群,然后创建关联层。 AWS OpsWorks 控制台结合了这些步骤;层创建会自动注册指定的集群。 如果您使用 AWS OpsWorks API、CLI 或 SDK,则必须使用单独的操作来注册集群并创建关联层。 [强调我的]
您声明您尝试将EcsClusterArn
添加到堆栈和层,但没有成功,但错误消息确认Amazon ECS 集群必须注册到层的首先堆栈,而您的示例模板实际上缺少这方面?以防万一,您可能只需要重复您的响应。来自AWS::OpsWorks::Layer
的片段也在AWS::OpsWorks::Stack
内:
"Attributes" :
"EcsClusterArn" :
"Fn::Join" : [ "", [ "arn:aws:ecs:",
"Ref" : "AWS::Region"
, ":",
"Ref" : "AWS::AccountId"
, ":cluster/",
"Ref" : "ecsCluster"
] ]
,
【讨论】:
是的,这就是我之前尝试过的,但从我发布的内容中删除了它。我只是仔细检查过,它仍然给我同样的错误。以上是关于如何在 CloudFormation 中向 Opsworks Stack 注册 ECS 集群?的主要内容,如果未能解决你的问题,请参考以下文章
AWS CloudFormation 脚本失败 - 不允许 Cognito 使用您的电子邮件身份
如何在 CloudFormation 中启用 VirtualMFADevice?
如何在 cloudformation“Fn::Sub”中转义“$”
如何知道 sam/cloudformation 堆栈 lambda 正在执行啥