我试图定义一个Cassandra节点的集群,以及其他一些实例(一些中间件和应用程序服务器)。 我希望能够将Cassandra节点的(内部)IP地址添加到中间件的configuration中,并将第一个Cassandra节点的IP添加到其他节点的configuration中,作为种子节点。 我能完全从模板内完成吗? (在AMI中调用脚本是可行的,集中式configuration或任何非平台提供的远程数据库都不是)
谢谢! 安德拉斯
编辑:我忘了提及我还需要更新与实例的IP相关的安全组。
在AWS文档中进行了一些挖掘之后,我发现您可以引用在同一模板中创build的资源的属性,只要它们在您的引用之前定义了b)不指向正在创build的资源循环依赖)
b)意味着要找出一个EC2节点自己的IP,我确实必须调用上面提到的aws URL ceejayoz
这是我对Cassandra节点的实例资源的定义。 请注意,我已经在configuration文件中放置标记,以便能够安全地插入正确的值,但是您可以随时恢复为简单地将默认值(例如“initial_token:0”replace为“initial_token:123”)
"Cas1" : { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "opscenter-free" : [], "pyOpenSSL" : [] } } }, "services" : { "sysvinit" : { "cassandra" : { "enabled" : "true", "ensureRunning" : "true" }, "opscenterd" : { "enabled" : "true", "ensureRunning" : "true" } } } } }, "Properties" : { "SecurityGroups" : [ { "Ref" : "CommonSecurityGroup" }, { "Ref" : "OpsCenterSecurityGroup" } ], "KeyName" : { "Ref" : "KeyName" }, "InstanceType" : { "Ref" : "CassandraInstanceType" }, "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "CassandraInstanceType" }, "Arch" ] } ] }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -v\n", "MY_IP=`(curl http://169.254.169.254/latest/meta-data/local-ipv4)`\n", "sed -i 's/REPLACE_WITH_TOKEN/0/g' /etc/cassandra/conf/cassandra.yaml\n", "sed -i 's/REPLACE_WITH_MY_IP/'$MY_IP'/g' /etc/cassandra/conf/cassandra.yaml\n", "sed -i 's/REPLACE_WITH_SEED_IP/'$MY_IP'/g' /etc/cassandra/conf/cassandra.yaml\n", "sed -i 's/REPLACE_WITH_MAX_HEAP_SIZE/8G/g' /etc/cassandra/conf/cassandra-env.sh\n", "sed -i 's/REPLACE_WITH_HEAP_NEWSIZE/4G/g' /etc/cassandra/conf/cassandra-env.sh\n", "yum update -y aws-cfn-bootstrap\n", "/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackName" }, " -r Cas1 ", " --access-key ", { "Ref" : "HostKeys" }, " --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, " --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n", "sed -i 's/127.0.0.1/'$MY_IP'/g' /etc/opscenter/opscenterd.conf\n", "sed -i 's/#passwd_file/passwd_file/g' /etc/opscenter/opscenterd.conf\n", "echo 'xxx:xxx:admin' > /etc/opscenter/.passwd\n", "rm -fR /var/lib/cassandra/data\n", "rm -fR /var/lib/cassandra/commitlog\n", "mkdir /var/lib/cassandra/data\n", "mkdir /var/lib/cassandra/commitlog\n", "chown -R cassandra:cassandra /var/lib/cassandra\n", "service cassandra start\n", "service opscenterd start\n" ]]}} } },
后续节点的configuration是相同的,除了线路
"sed -i 's/REPLACE_WITH_SEED_IP/'$MY_IP'/g' /etc/cassandra/conf/cassandra.yaml\n",
引用种子(第一个)节点的IP地址
"sed -i 's/REPLACE_WITH_SEED_IP/", { "Fn::GetAtt" : ["Cas1", "PrivateIp"] }, "/g' /etc/cassandra/conf/cassandra.yaml\n",
关于将实例IP添加到安全组,这似乎是不必要的,您可以创build一个组,并添加Ingress资源,在其中您引用该组作为源
"CommonSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enables", "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : "0.0.0.0/0" } ] } }, "OpsCenterSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enables", "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "8888", "ToPort" : "8888", "CidrIp" : "0.0.0.0/0" }, "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "61620", "ToPort" : "61621", "SourceSecurityGroupName" : { "Ref": "CommonSecurityGroup" } } ] } }, "CassandraThriftIngress" : { "Type" : "AWS::EC2::SecurityGroupIngress", "Properties" : { "GroupName": { "Ref": "CommonSecurityGroup" }, "IpProtocol" : "tcp", "FromPort" : "9160", "ToPort" : "9160", "SourceSecurityGroupName" : { "Ref": "CommonSecurityGroup" } } }, "CassandraData" : { "Type" : "AWS::EC2::SecurityGroupIngress", "Properties" : { "GroupName": { "Ref": "CommonSecurityGroup" }, "IpProtocol" : "tcp", "FromPort" : "7000", "ToPort" : "7001", "SourceSecurityGroupName" : { "Ref": "CommonSecurityGroup" } } }, "CassandraJMX" : { "Type" : "AWS::EC2::SecurityGroupIngress", "Properties" : { "GroupName": { "Ref": "CommonSecurityGroup" }, "IpProtocol" : "tcp", "FromPort" : "7199", "ToPort" : "7199", "SourceSecurityGroupName" : { "Ref": "OpsCenterSecurityGroup" } } },
是的,你可以在模板中完全做到这一点。 下面是定义三个实例的模板的“资源”部分:两个Cassandra实例和一个中间件实例。
第二个Cassandra实例接收第一个的IP作为用户数据。 中间件实例接收两个Cassandra实例的IP,也作为用户数据。
两个Cassandra实例都被添加到“cassandra-nodes”安全组中。 我没有包括这个定义,但在片段部分有一个安全组模板的例子。 您不需要手动将其IP添加到SG,只需在描述实例时引用它。
"Resources" : { "CassOneInstance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : "ami-123", "InstanceType": "c1.medium", "SecurityGroups" : [ "cassandra-nodes" ] } }, "CassTwoInstance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : "ami-123", "InstanceType": "c1.medium", "SecurityGroups" : [ "cassandra-nodes" ], "UserData" : { "Fn::Base64" : { "Fn::Join" : [ ":", [ { "Fn::GetAtt" : [ "CaseOneInstance", "PrivateIP" ] } ] } }, } }, "MiddleWareInstance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : "ami-123", "InstanceType": "c1.medium", "UserData" : { "Fn::Base64" : { "Fn::Join" : [ ":", [ { "Fn::GetAtt" : [ "CaseOneInstance", "PrivateIp" ] }, { "Fn::GetAtt" : [ "CaseTwoInstance", "PrivateIp" ] } ] } }, } } }
在AMI中调用脚本是可以的
如果是这样,所有你需要的是cURL和EC2的内部元数据服务。 从实例来看:
curl http://169.254.169.254/latest/meta-data/local-ipv4
在http://169.254.169.254/latest/meta-data/ – 主机名,安全组,实例ID等,还有一大堆其他可用的元数据。