Após algumas pesquisas nos documentos da AWS, descobri que é possível fazer referência às propriedades dos recursos criados no mesmo modelo, desde que a) sejam definidos antes de sua referência b) não apontem para o recurso que está sendo criado (sem dependências circulares)
b) implica que, para descobrir um IP próprio do nó EC2, eu realmente tenho que chamar o URL aws que o ceejayoz menciona acima
Esta é a minha definição de um recurso de instância para um nó do Cassandra. Observe que eu coloquei marcadores no arquivo de configuração para inserir com segurança valores corretos, mas você sempre pode reverter para simplesmente substituir os valores padrão (por exemplo, "initial_token: 0" com "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"
]]}}
}
},
A configuração dos nós subsequentes é a mesma, exceto a linha
"sed -i 's/REPLACE_WITH_SEED_IP/'$MY_IP'/g' /etc/cassandra/conf/cassandra.yaml\n",
Referencia o endereço IP do nó semente (primeiro)
"sed -i 's/REPLACE_WITH_SEED_IP/", { "Fn::GetAtt" : ["Cas1", "PrivateIp"] }, "/g' /etc/cassandra/conf/cassandra.yaml\n",
Com relação à adição de IPs de instância a grupos de segurança, isso parece desnecessário. Basta criar um grupo e adicionar recursos do Ingress a ele nos quais você faz referência ao grupo como a Origem
"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" }
}
},