Я пытаюсь определить кластер узлов Cassandra вместе с некоторыми другими экземплярами (некоторым промежуточным программным обеспечением и серверами приложений). Я хотел бы иметь возможность добавлять (внутренние) IP-адреса узлов Cassandra в конфигурацию промежуточного программного обеспечения, а также добавлять IP-адрес первого узла Cassandra в конфигурацию других узлов в качестве начального узла. Могу ли я добиться этого полностью из шаблона? (запуск сценариев в AMI - это нормально, централизованная конфигурация или любая удаленная база данных, не предоставляемая платформой, - нет)
Спасибо! Андраш
изменить: я забыл упомянуть, что мне также нужно будет обновить соответствующие группы безопасности с IP-адресами экземпляров.
Покопавшись в документации AWS, я обнаружил, что вы можете ссылаться на свойства ресурсов, созданных в том же шаблоне, если они: а) определены до вашей ссылки б) не указывают на создаваемый ресурс (нет круговые зависимости)
b) подразумевает, что для того, чтобы узнать собственный IP-адрес узла EC2, мне действительно нужно вызвать URL-адрес aws, упомянутый выше ceejayoz
Это мое определение ресурса экземпляра для узла Cassandra. Обратите внимание, что я поместил маркеры в файл конфигурации, чтобы можно было безопасно вставлять правильные значения, но вы всегда можете вернуться к простой замене значений по умолчанию (например, «initial_token: 0» на «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"
]]}}
}
},
Конфигурация последующих узлов такая же, за исключением строки
"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-адресов экземпляра в группы безопасности, это кажется ненужным, вы можете просто создать группу и добавить в нее ресурсы 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-адрес первого в качестве пользовательских данных. Экземпляр промежуточного программного обеспечения получает IP-адреса обоих экземпляров Cassandra также в виде пользовательских данных.
Оба экземпляра 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/
- имя хоста, группы безопасности, идентификатор экземпляра и т. д.