0

我正在尝试启动并运行一个Stacker项目(在幕后使用对流层),并且我已经能够创建多个资源,但无法弄清楚子网部分。我尝试以几种不同的方式将它们传递到我的蓝图类中,但我认为这是最接近的,它类似于其他不会彻底爆炸的实现。这个想法是接受这样的子网的一些配置。

在我的my_cluster.yaml,我有:

 stacks:
 ...
  - name: cluster-networks
    description: "Networks for an ECS cluster"
    class_path: blueprints.networks.Networks
    variables:
      Networks: 
        InternalComms:
          AssignPublicIp: False
          SecurityGroups: 
            - sg-id
          Subnets: 
            - subnet-id1
            - subnet-id2

为了阅读该配置,我有一个名为的蓝图blueprints/networks.py,其中包含以下内容:

class Networks(Blueprint):
"""Manages creation of networks for ECS clusters"""

# Variables that are passed from the my_cluster.yaml
VARIABLES = {
    "Networks": {
        "type": TroposphereType(ecs.AwsvpcConfiguration, many=True),
        "description": "Dictionary for ECS cluster networks"
    }
}

def create_template(self):
    """method that Stacker calls to manipulate the template(s)"""
    variables = self.get_variables()
    for config in variables['Networks']:
        network = ecs.NetworkConfiguration(config)
        t.add_resource(network)
        # do other useful stuff like set outputs

如果您想知道为什么我创建一个AwsvpcConfiguration对象然后再从中创建一个NetworkConfiguration对象,原因是我在采用NetworkConfiguration对象之前尝试在使用对象时传递此信息,AwsvpcConfiguration但它也不起作用。我使用这个文件来指导我,因为它是定义这些对象的地方。下一步是build资源,所以当我通过运行以下命令执行此操作时:

stacker build path/to/my.env path/to/my_cluster.yaml

我收到一条错误消息:

stacker.exceptions.ValidatorError: Validator 'AwsvpcConfiguration.create' 
failed for variable 'Networks' with value 
'{'InternalComms': {'AssignPublicIp': False, 'SecurityGroups': ['sg-id'], 'Subnets': ['subnet-id1', 'subnet-id2']}}': 
TypeError: _from_dict() argument after ** must be a mapping, not str

这可能是我在 stacker、yaml 和 python 方面缺乏技能,但我被难住了,已经有一天左右的时间了。

我无法弄清楚如何将 yaml 中的配置作为字典传递到蓝图中,就像我对在 AWS-land 中成功创建的其他资源以相同的方式做的那样。如果您能指出错误,我将非常感激,并且肯定会告诉圣诞老人您有多好。

4

1 回答 1

1

对流层维护者/堆栈器作者在这里。所以有几点:

  1. 您想要使用TroposphereType(ecs.NetworkConfiguration, many=True),因为这是您想要创建的对象类型。
  2. ecs.NetworkConfiguration ( https://github.com/cloudtools/troposphere/blob/master/troposphere/ecs.py#L71 ) 是一个 AWSProperty 类型,这意味着它里面的值,如果使用“many”需要是每个字典列表: http: //stacker.readthedocs.io/en/latest/blueprints.html#property-types

所以我认为你想要的是你的配置

variables: Networks: - AwsvpcConfiguration: AssignPublicIp: False SecurityGroups: - sg-id Subnets: - subnet-id1 - subnet-id2

这是因为TroposphereType期望您传递类型期望的确切参数。ANetworkConfiguration需要一个键 ,AwsvpcConfiguration并且您传递的值是AwsvcpConfiguration对象所期望的值。

现在更大的问题是您希望如何使用这些对象。在 Cloudformation/troposphere 中,属性类型不是自己创建的——它们用作实际资源的属性——在这种情况下是ecs.Service类型。您不打算将服务包含在同一个蓝图中吗?如果没有,您打算如何与这些服务所在的其他蓝图共享这些属性?

更好的选择可能是拥有一个构建服务的蓝图以及它的NetworkConfiguration. 然后,如果您希望使用该蓝图在多个堆栈之间轻松共享相同的 NetworkConfiguration,您可以使用 YAML 锚点执行以下操作:

common_network_configuration: &common_network_configuration - AwsvpcConfiguration: AssignPublicIp: False SecurityGroups: - sg-id Subnets: - subnet-id1 - subnet-id2

然后在任何你想要的变量中使用它,比如:

variables: << : *common_network_configuration

我希望这是有道理的 - 如果您还有任何问题,您也可以随时通过 stacker Slack 与我们联系:https ://empire-slack.herokuapp.com/

祝你有个好的一天!

于 2017-12-20T22:50:21.293 回答