Amazon ec2 使用对流层动态创建n个ec2实例

Amazon ec2 使用对流层动态创建n个ec2实例,amazon-ec2,amazon-cloudformation,troposphere,Amazon Ec2,Amazon Cloudformation,Troposphere,我刚刚进入EC2,云形成(和对流层),等等。我试着从一个简单的硒网格开始,每晚运行。现在,我们在需要时使用旋转12个selenium节点(每个节点都在自己的EC2实例上)。堆垛一次只能堆放几个小时。未来我们很可能需要更多的节点,所以我不想静态地设置节点的数量,而是尝试设置它,以便Jenkins可以动态地增加节点的数量 现在,我已经有了一个简单的for循环,它看起来应该工作得很好——特别是在看了一堆示例之后: for i in range(numNodes): instance = ec2

我刚刚进入EC2,云形成(和对流层),等等。我试着从一个简单的硒网格开始,每晚运行。现在,我们在需要时使用旋转12个selenium节点(每个节点都在自己的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
我甚至试着把所有的东西都传给构造器

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这里是对流层维护程序。您在什么时候得到ValueError?你能分享完整的堆栈跟踪吗

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

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)
您甚至可以将其缩短为:

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

无论如何,这似乎不是你的问题-因此,如果你能分享完整的堆栈跟踪,以获得对你有帮助的错误,以及你正在使用的python和troposphere的版本。

好吧,一旦我发现我是个笨蛋,我打算删除这个问题。。。但是,为了全人类的利益,关于删除“回答的问题”的那个小信息,让我感到内疚。希望其他人能从我的错误中吸取教训

至于答案

结果证明对流层并没有什么问题(我认为这是我的错)。我完全忘记了Selenium Hub,它是它自己的实例,但不是根据需要的节点数量动态设置的。我只为中心添加了部分资源。你猜对了-我忘了指定ImageId kwarg。一旦我添加了这一点(以及其他一些Kwarg),一切工作都完美无缺


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

实际上,我试图缩短它并将其传递给构造函数,但仍然得到相同的错误。对不起,太早点击return。我用你要求的信息更新了这个问题。哦,太好了,很高兴你弄明白了。现在,我真的在想,是否有一种方法可以让这个异常指出引起问题的对象的标题(如果它有),这肯定会对您有所帮助。我会看一看,谢谢你的好话:)顺便说一句,我创建了一个公关,应该可以更轻松地解决这些问题:
for i in range(numNodes):
    instance = template.add_resource(
        ec2.Instance(
            "Node{}".format(str(i)),
            ImageId=Ref(Image)
            UserData=Base64(Join("", userData)),
            InstanceType=Ref(NodeSize),
            KeyName=Ref(SSHKey),
            SecurityGroups=[Ref("NodeSecurityGroup")],
            IamInstanceProfile="SeleniumNode",
        )
    )