使用Troposphere动态创建n个ec2实例

时间:2016-10-18 21:58:34

标签: amazon-ec2 amazon-cloudformation troposphere

我刚刚进入EC2,CloudFormation(和Troposphere)等等。我试图从一个简单的Selenium Grid开始每晚运行。现在,我们在需要时使用12个硒节点(每个节点都有自己的EC2实例)。堆栈一次只能运行几个小时。我们很可能在将来需要更多,所以我不是静态地设置节点数,而是试图设置它以便Jenkins可以动态增加节点数。

现在,我有一个简单的for循环看起来应该可以正常工作 - 特别是在看了一堆例子之后:

for i in range(numNodes):
    instance = ec2.Instance("Node{}".format(str(i)))
    instance.ImageId = Ref(Image)
    instance.UserData = Base64(Join("", userData))
    instance.InstanceType = Ref(NodeSize)
    instance.KeyName = Ref(SSHKey)
    instance.SecurityGroups = [Ref("NodeSecurityGroup")]
    instance.IamInstanceProfile = "SeleniumNode"
    template.add_resource(instance)

完整堆栈跟踪:

        Traceback (most recent call last):
  File "C:/dev/source/admin/scripts/troposphere/seleniumGrid.py", line 171, in <module>
    print(template.to_json())
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\site-packages\troposphere\__init__.py", line 543, in to_json
    sort_keys=sort_keys, separators=separators)
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\json\__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 200, in encode
    chunks = list(chunks)
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 429, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 403, in _iterencode_dict
    yield from chunks
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 403, in _iterencode_dict
    yield from chunks
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 436, in _iterencode
    o = _default(o)
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\site-packages\troposphere\__init__.py", line 440, in default
    return obj.JSONrepr()
  File "C:\Users\Sathed\AppData\Local\Programs\Python\Python35-32\lib\site-packages\troposphere\__init__.py", line 223, in JSONrepr
    "Resource %s required in type %s" % (k, rtype))
ValueError: Resource ImageId required in type AWS::EC2::Instance

My Image参数如下所示:

Image = template.add_parameter(Parameter(
"Image",
    Type="AWS::EC2::Image::Id",  # I even tried setting this to "String"
    Description="AMI To use for all windows grid instances.",
    Default="ami-c06b24a0"  
))

我甚至尝试将所有内容传递给构造函数。

for i in range(numNodes):
    instance = ec2.Instance("Node{}".format(str(i)),
                            ImageId=Ref(Image),
                            UserData=Base64(Join("", userData)),
                            InstanceType=Ref(NodeSize),
                            KeyName=Ref(SSHKey),
                            SecurityGroups=[Ref("NodeSecurityGroup")],
                            DependsOn=["NodeSecurityGroup", "WindowsHub"],
                            IamInstanceProfile="SeleniumNode")
    template.add_resource(instance)

但我仍然遇到同样的错误。我确定这是愚蠢的事情,但它变得非常恼人。有什么想法吗?

另外,当我尝试打印JSON模板时,我收到错误。

print(template.to_json())

对流层1.8.2

Python 3.5.2

2 个答案:

答案 0 :(得分:1)

这里有对流层维护者。你在什么时候得到ValueError?你能分享完整的堆栈跟踪吗?

有一件事可能无法解决这个问题,但我想我会指出,在创建对象后,您不需要指定实例的每个单独属性。相反,您通常会使用此代码:

.attr("routerLink",function (d) { return 'search-results'; })

你甚至可以将它缩短为:

for i in range(numNodes):
    instance = ec2.Instance(
        "Node{}".format(str(i)),
        ImageId=Ref(Image)
        UserData=Base64(Join("", userData)),
        InstanceType=Ref(NodeSize),
        KeyName=Ref(SSHKey),
        SecurityGroups=[Ref("NodeSecurityGroup")],
        IamInstanceProfile="SeleniumNode",
    )
    template.add_resource(instance)

无论如何,这似乎不是你的问题 - 所以如果你可以分享完整的堆栈跟踪以获得有用的错误,以及python和amp;的版本。你正在使用的对流层。

答案 1 :(得分:1)

好吧,一旦我发现自己是个傻瓜,我就会删除这个问题......但是为了全人类而删除“回答问题”的那条小信息,yadda yadda yadda让我感到内疚。希望那里的其他人可以从我的错误中吸取教训。

至于答案......

事实证明对流层没有任何问题(我认为这是我的错)。我完全忘记了Selenium Hub,它是它自己的实例,但不是根据所需的节点数动态设置的。我只是部分添加了集线器的资源。你猜它 - 我忘了指定ImageId kwarg。一旦我添加了(和其他几个kwargs),一切都完美无瑕。

向@phobologic和所有其他Troposphere维护者大声疾呼。因为你,我能够将2500多行JSON对象变成一个更容易维护的~175行python脚本!