CloudFormation / EC2 - acessa o endereço IP da instância EC2 no modelo?

2

Estou tentando definir um cluster de nós do Cassandra, junto com algumas outras instâncias (alguns servidores de middleware e de aplicativo). Gostaria de poder adicionar os endereços IP (internos) dos nós do Cassandra à configuração do middleware e também adicionar o IP do primeiro nó do Cassandra à configuração dos outros nós, como um nó de origem. Posso conseguir isso inteiramente de dentro do modelo? (chamar scripts na AMI é ok, configuração centralizada ou qualquer tipo de banco de dados remoto não fornecido pela plataforma não é)

obrigado! Andras

edit: esqueci de mencionar que eu também precisaria estar atualizando os grupos de segurança relevantes com os IPs das instâncias.

    
por pgn 25.04.2012 / 23:57

3 respostas

4

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" }
        }
    },
    
por 27.04.2012 / 09:19
2

invoking scripts in the AMI is ok

Se sim, tudo o que você precisa é do serviço de metadados internos do cURL e do EC2. Da instância:

curl http://169.254.169.254/latest/meta-data/local-ipv4

Há muitos outros metadados disponíveis em http://169.254.169.254/latest/meta-data/ - nome do host, grupos de segurança, ID da instância, etc.

    
por 26.04.2012 / 00:08
2

Sim, você pode fazer isso inteiramente dentro do modelo. Abaixo está a seção "Recursos" de um modelo que define três instâncias: Duas instâncias do Cassandra e uma instância de middleware.

A segunda instância do Cassandra recebe o IP do primeiro como dados do usuário. A instância de middleware recebe os IPs de ambas as instâncias do Cassandra, também como dados do usuário.

Ambas as instâncias do Cassandra são adicionadas ao grupo de segurança 'nós-da-cassandra'. Eu não incluí a definição para isso, mas há um exemplo de um modelo de grupo de segurança no snippets . Você não precisa adicionar manualmente seus IPs ao SG, apenas referenciá-lo ao descrever a instância.

"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" ] }
                ]
            }
         },
      }
    }
}
    
por 30.04.2012 / 23:56