_Esta edição foi originalmente aberta por @coolgooze como hashicorp/terraform#11713. Ele foi migrado aqui como parte da divisão do provedor . O corpo original da edição está abaixo._
ASG
recurso "aws_autoscaling_group" "REDIS_ASG" {
nome = "${var.environment}-REDIS_ASG"
launch_configuration = "${aws_launch_configuration.redis_launch_conf.name}"
#availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
vpc_zone_identifier = ["${data.aws_subnet.PrivateDBSubnetAZ1.id}","${data.aws_subnet.PrivateDBSubnetAZ2.id}","${data.aws_subnet.PrivateDBSubnetAZ3.id}"]
min_size = 1
max_size = 1
capacidade_desejada = 1
health_check_grace_period = 600
health_check_type = "EC2"
force_delete = "falso"
terminação_policies = ["OldestInstance"]
marcação {
chave = "Nome"
value = "${var.environment}-int-redis"
propagate_at_launch = true
}
}
estou tentando criar um registro A
recurso "aws_route53_record" "redis" {
zone_id = "${data.aws_route53_zone.dns.zone_id}"
name = "redis-${var.environment}.${data.aws_route53_zone.dns.name}"
tipo = "A"
tt = "60"
registros = ["${aws_autoscaling_group.REDIS_ASG.private_ip}"]
}
Saída-
Eu só precisava disso hoje. Eu adoraria que isso fosse uma coisa real.
Eu corri para uma necessidade para isso hoje. Eu adoraria que isso existisse. Alguma atualização sobre o pedido?
Olá – Você pode descrever o caso de uso aqui? Estou curioso para saber por que você deseja o IP direto de qualquer instância que esteja em um grupo de dimensionamento automático, em vez de se conectar por meio de um balanceador de carga.
Se não me engano, uma vantagem específica de um ASG é garantir que você tenha um certo número de instâncias disponíveis e em execução, não que uma delas exista em um determinado IP.
Se o recurso ASG exportasse um IP privado e, no lado da AWS, o ASG alterasse as instâncias por qualquer motivo, esse IP poderia ficar obsoleto até seu próximo plano e aplicação, certo? Nesse caso, pode haver uma janela de tempo em que seu registro A o direciona para um IP incorreto, correto? Onde, como se o registro A apontasse para um IP atribuído a um balanceamento de carga, o rollover aconteceria automaticamente.
Estou curioso para saber como expor isso seria usado de maneira confiável e estável. Obrigado!
@catsby Você está correto ao dizer que o IP seria obsoleto e o Terraform precisaria ser executado para atualizar o registro A anexado ao registro Route53.
Temos casos de uso em que temos um conjunto de servidores que executam tarefas diferentes. Tudo é controlado no fantoche e no Terraform. Agora temos um módulo que constrói uma contagem (normalmente). O que queríamos fazer era colocá-los em um ASG para ter autocura no caso de um nó falhar. No entanto, não podemos avançar com os testes porque não há saída de ips privados ou uma lista de nós.
Iniciamos um efeito há algum tempo para remover o endereço IP das configurações e trocar para nomes DNS. Seria a cereja do bolo se pudéssemos construir uma maneira de autocurar esses servidores em caso de falha da instância aws usando ASG.
+1
Outro caso de uso
https://github.com/terraform-community-modules/tf_aws_bastion_s3_keys
Isso configura um bastião em um grupo de escalonamento automático min=max=desired=1. O raciocínio por trás disso é relançar automaticamente o bastião se ele cair. Sem isso, no entanto, tenho que verificar depois para ver qual ip o bastião realmente recebeu.
Seria muito útil ter esse recurso. Os usuários podem executar tipos de cargas de trabalho únicas com uma lista de IPs conhecidos para o ASG em um null_resource. +1 para mim também.
@catsby Veja meu comentário na edição fechada migrada aqui: https://github.com/hashicorp/terraform/issues/11713
Repetir:
Muito útil, fornecerá a mesma funcionalidade que o CloudFormation. Podemos simplesmente esperar que o ASG termine de criar todas as instâncias e reporte com ips privados, ids de instância etc.
Também ninguém diz que ASG tem que estar relacionado a um ELB, no nosso caso temos as instâncias por trás do HAProxy então precisamos saber seus IP's.
Isso está aberto desde fevereiro, é realmente tão difícil de resolver?
@catsby Outro exemplo, quero criar registros DNS do Route53 e verificações de integridade após o lançamento de instâncias:
# Host-specific A records for both load-balancers
resource "aws_route53_record" "service-record" {
zone_id = "<my-zone-id>"
count = 2
name = "service-lb-${format("%03d", count.index + 1)}.mydomain.com"
type = "A"
ttl = "60"
records = ["${element(aws_instance.lb-service.*.public_ip, count.index)}"]
}
# Health checks for each of the load balancers
resource "aws_route53_health_check" "service-healthcheck" {
ip_address = "${element(aws_instance.lb-service.*.public_ip, count.index)}"
count = 2
port = 50000
type = "HTTP"
resource_path = "/health"
failure_threshold = "5"
request_interval = "30"
tags = {
Name = "service-${format("%03d", count.index + 1)}.production"
}
}
# Group consisting of 2 alias records to the host records, with associated health checks, having weighted routing
resource "aws_route53_record" "service-group" {
zone_id = "<my-zone-id>"
count = 2
name = "service.mydomain.com"
type = "A"
weighted_routing_policy = {
weight = "50"
}
health_check_id = "${element(aws_route53_health_check.service-healthcheck.*.id, count.index)}"
set_identifier = "service${format("%03d", count.index + 1)}"
alias {
name = "${element(aws_route53_record.service-record.*.fqdn, count.index)}"
zone_id = "<my-zone-id>"
evaluate_target_health = true
}
}
Quando as instâncias são executadas via ASG, não há como fazer isso. Somos forçados a mover esse código para os dados do usuário, o que é um grande PITA.
+1
alguma atualização disso?
Não sou contra esse recurso _em geral_, mas tenho opiniões sobre como ele deve ser implementado. Também serei franco e direi que é improvável que nós (HashiCorp) cheguemos a esse recurso em breve, mas agradecemos contribuições se alguém puder pegá-lo.
Sobre como implementar:
Portanto, o problema aqui em resumo é que os endereços IP não são retornados por padrão e você precisa fazer algumas chamadas de API adicionais para obtê-los. Para configurações grandes, essas chamadas de API extras são adicionadas rapidamente, portanto, por padrão, não devemos incluir Endereços IP de instância no estado de Grupos de AutoScaling . Reconheço que é um recurso útil, mas também acho que não será usado com frequência, portanto, por padrão, não devemos consumir todas essas chamadas de API.
Dito isso, acredito/proponho que possamos oferecer suporte a essa funcionalidade com uma fonte de dados:
data.aws_autoscaling_group.group
(singular) não deve ser confundido com data.aws_autoscaling_groups
(plural)data.aws_autoscaling_groups
que apenas retorna nomes)false
, como get_instance_properties
para instruir a fonte de dados a procurar atributos de instância:DescribeInstances
Alternativamente, poderíamos expandir a fonte de dados data.aws_autoscaling_groups
, mas acho que prefiro a separação.
Para obter o(s) endereço(s) IP da(s) Instância(s), precisamos chamar DescribeInstances para cada uma. Felizmente, podemos usar um EC2Filter e filtrar por requester-id
, neste caso, o ID de grupo de AutoScaling, para que não precisemos agrupar os IDs de instância da saída DescribeASG e, em seguida, alimentá-los na chamada DescribeInstances .
Acredito que essa nova fonte de dados manteria essas informações de instância em TypeSet
de instâncias. Infelizmente você não pode referenciar diretamente o valor em um conjunto com coisas como element(set, count)
. Então, se você quiser uma lista de endereços IP, podemos querer pegar os resultados da chamada DescribeInstances
e agregar todos os ips públicos em um campo calculado public_ips
e ips privados em private_ips
.
Então, no final, a saída dessa fonte de dados seria assim:
Como isso soa?
```hcl
recurso "autoscaling_group" "exemplo" {
[...]
}
data "autoscaling_group" "example_ips" {
autoscaling_id = "${aws_autoscaling_group.example.id}"
# Busca informações da instância
# Recupera informações da instância
# Recupera public_ip's
# Recupera private_ip's
get_instance_properties = true
}
resource "aws_route53_record" "service-record" {
zona_id = "
contagem = 2
name = "service-lb-${format("%03d", count.index + 1)}.mydomain.com"
tipo = "A"
tt = "60"
registros = ["${element(data.aws_autoscaling_group.example_ips.private_ips, count.index)}"]
}
@catsby Eu amo isso e ajudaria muito.
@catsby linda!
qualquer atualização sobre isso, na real necessidade desta solução.
Isso foi analisado? uma rolha completa sobre o que sou obrigado a fazer.
alguma atualização disso?
Isso seria incrível de ter!
Isso seria glorioso! Já que o Lambda acionado pelo CloudWatchEvent é uma bagunça!
Precisa desse também
Alguém encontra solução ou solução para este problema? Isso é completamente uma rolha para o que eu preciso fazer.
+1
+1
+1
+1
+1
+1
+1
+1
Aqui estão algumas soluções que eu implemento:
Use o módulo terraform-aws-modules/autoscaling/aws
para lançar meus ASG's
Marque o ASG e use a fonte de dados aws_instance
para pesquisar as instâncias com base nas tags. Então faça o que eu preciso fazer com os dados
Ao usar um ASG para um Bastion Host. Eu crio um iam_instance_profile
para o ASG que permite que a própria instância atualize seu próprio registro route53 ao inicializar usando um script de configuração de inicialização.
Espero que isto ajude
+1
+1
Existe atualmente alguma solução alternativa disponível?
Dessa forma, me permitiu obter ips de nós de trabalho:
data "aws_instances" "workers" {
instance_tags {
Name = "lexsys-eks-asg"
}
}
output "private-ips" {
value = "${data.aws_instances.workers.private_ips}"
}
output "public-ips" {
value = "${data.aws_instances.workers.public_ips}"
}
Outputs:
private-ips = [
10.0.0.75,
10.0.1.87
]
public-ips = [
52.44.215.211,
54.153.70.110
]
Claro, essa solução alternativa tem as limitações, mas funcionou para mim.
@catsby Um caso de uso é para configuração de cluster. Em tal cenário, queremos poder fornecer apenas as chaves SSH das instâncias para pessoas que desejam testar um cluster como kafka, zookeeper, elasticsearch etc, sem precisar fornecer acesso ao console da AWS. Se o terraform pudesse simplesmente gerar o endereço IP privado, os solucionadores de problemas teriam uma lista de endereços IP para fazer login simplesmente com suas chaves SSH e sem exigir acesso ao Console AWS.
+1
@catsby Sim, outro caso de uso é ao criar um cluster kubernetes por meio de um asg. você precisa do ip privado do mestre para alimentar os trabalhadores. Existe alguém que conhece um trabalho em torno disso?
+1
+1
+1. Meu caso de uso envolve o Hashicorp Vault, que precisa ser inicializado antes de ser reconhecido como um nó íntegro pelo balanceador de carga.
+1
Alguma solução alternativa para o Google Cloud Platform? Tem o mesmo problema com google_compute_instance_group_manager
.
@lexsys27 a pergunta é específica para quando as instâncias são criadas via aws_autoscaling_group
@KIVagant Receio que você precise esperar pacientemente como o resto de nós (desde fevereiro de 2017) para que isso seja incluído no terraform, meus prognósticos seriam em torno da versão 2.27 ... provavelmente :-)
@igoratencompass Eu uso aws_autoscaling_group
para criar instâncias.
Eu etiqueto as instâncias no modelo e uso essa tag para recuperar IPs na seção data
.
Vejo que não estava ciente desse recurso de módulo de dados.
https://github.com/terraform-providers/terraform-provider-aws/issues/511#issuecomment -401362499 é uma solução alternativa, mas tenha cuidado na página do documento
Observação: é altamente desencorajado o uso dessa fonte de dados para consultar instâncias efêmeras (por exemplo, gerenciadas por meio de grupo de dimensionamento automático), pois a saída pode mudar a qualquer momento e você precisará executar a aplicação novamente sempre que uma instância for ativada ou morrer.
Esta nota é outro motivo para implementar esta nova fonte de dados
você pode extrair todos os dados da instância com uma pesquisa rodada.
(exemplo supondo que algum asg chamado aws_autoscaling_group.one já esteja definido)
data "aws_instances" "nodes" {
depends_on = [ "aws_autoscaling_group.one" ]
instance_tags {
Name = "some_unique_tag_in_your_asg"
}
}
data "aws_instance" "asg-one-instances" {
count = "${ var.asg_one_count }"
depends_on = ["data.aws_instances.nodes"]
instance_id = "${data.aws_instances.nodes.ids[count.index]}"
}
output "private-ips" {
value = "${ data.aws_instance.asg-one-instances.*.private_ip }"
}
output "public-ips" {
value = "${ data.aws_instance.asg-one-instances.*.public_ip }"
}
output "private-dnsnames" {
value = "${ data.aws_instance.asg-one-instances.*.private_dns }"
}
output "public-dnsnames" {
value = "${ data.aws_instance.asg-one-instances.*.public_dns }"
}
mas eu preferiria ter os dados da instância diretamente disponíveis nos atributos asg.
@syncroswitch o problema que vejo com isso é a variável asg_one_count
. É um valor estático que irá/pode não corresponder ao estado real do ASG em execuções consecutivas, ou seja, o ASG cresceu ou diminuiu no tempo médio.
@syncroswitch @igoratencompass funciona para obter os endpoints e ips privados quando você inicia, que é o que é mais necessário.
Além disso, basta definir count = "${ var.asg_one_count }"
para count = ${aws_autoscaling_group.one.desired_capacity}
Se as pessoas realmente precisam de ips dinâmicos, devem escrevê-lo em python, bash, go, etc e chamá-lo de terraform e usá-lo em vez da capacidade desejada, mas duvido que seja realmente necessário ou desejado a longo prazo.
Comecei com a configuração do @syncroswitch e terminei com uma solução alternativa mais simples:
data "aws_instances" "ecs_instances_meta" {
instance_tags = {
# Use whatever name you have given to your instances
Name = var.ecs_cluster_name
}
}
output "ecs-private-ips" {
value = data.aws_instances.ecs_instances_meta.private_ips
}
Comentários muito úteis
Não sou contra esse recurso _em geral_, mas tenho opiniões sobre como ele deve ser implementado. Também serei franco e direi que é improvável que nós (HashiCorp) cheguemos a esse recurso em breve, mas agradecemos contribuições se alguém puder pegá-lo.
Sobre como implementar:
Portanto, o problema aqui em resumo é que os endereços IP não são retornados por padrão e você precisa fazer algumas chamadas de API adicionais para obtê-los. Para configurações grandes, essas chamadas de API extras são adicionadas rapidamente, portanto, por padrão, não devemos incluir Endereços IP de instância no estado de Grupos de AutoScaling . Reconheço que é um recurso útil, mas também acho que não será usado com frequência, portanto, por padrão, não devemos consumir todas essas chamadas de API.
Dito isso, acredito/proponho que possamos oferecer suporte a essa funcionalidade com uma fonte de dados:
data.aws_autoscaling_group.group
(singular) não deve ser confundido comdata.aws_autoscaling_groups
(plural)data.aws_autoscaling_groups
que apenas retorna nomes)false
, comoget_instance_properties
para instruir a fonte de dados a procurar atributos de instância:DescribeInstances
Alternativamente, poderíamos expandir a fonte de dados
data.aws_autoscaling_groups
, mas acho que prefiro a separação.Para obter o(s) endereço(s) IP da(s) Instância(s), precisamos chamar DescribeInstances para cada uma. Felizmente, podemos usar um EC2Filter e filtrar por
requester-id
, neste caso, o ID de grupo de AutoScaling, para que não precisemos agrupar os IDs de instância da saída DescribeASG e, em seguida, alimentá-los na chamada DescribeInstances .Acredito que essa nova fonte de dados manteria essas informações de instância em
TypeSet
de instâncias. Infelizmente você não pode referenciar diretamente o valor em um conjunto com coisas comoelement(set, count)
. Então, se você quiser uma lista de endereços IP, podemos querer pegar os resultados da chamadaDescribeInstances
e agregar todos os ips públicos em um campo calculadopublic_ips
e ips privados emprivate_ips
.Então, no final, a saída dessa fonte de dados seria assim:
Como isso soa?
```hcl
recurso "autoscaling_group" "exemplo" {
[...]
}
data "autoscaling_group" "example_ips" {
autoscaling_id = "${aws_autoscaling_group.example.id}"
# Busca informações da instância
# Recupera informações da instância
# Recupera public_ip's
# Recupera private_ip's
get_instance_properties = true
}
resource "aws_route53_record" "service-record" {"
zona_id = "
contagem = 2
name = "service-lb-${format("%03d", count.index + 1)}.mydomain.com"
tipo = "A"
tt = "60"
registros = ["${element(data.aws_autoscaling_group.example_ips.private_ips, count.index)}"]
}