ansible e recarregando o inventário dinâmico da AWS

7

Veja também: link .

Minha pergunta: existe uma maneira melhor de fazer o que está abaixo?

Eu tenho uma função ansible que provisiona máquinas da AWS e é executada corretamente (observe a tag provision ):

- name: AWS provision
  hosts: localhost
  gather_facts: no
  vars_files:
    - vars/dev.yml
  user: ec2-user
  roles:
    - provision
  tags:
    - provision

Eu, então, tenho uma função base , que desejo executar de forma independente (por exemplo, durante o desenvolvimento, por isso não preciso aguardar o reprovisionamento (observe a tag base ). uma reprodução find running instances que filtra e armazena os hosts no grupo started :

- name: find running instances
  hosts: localhost
  vars_files:
    - vars/dev.yml
  gather_facts: no
  tags:
    - base
  tasks:
    - name: gather remote facts
      ec2_remote_facts:
        region: "{{ target_aws_region }}"
        filters:
          instance-state-name: running
          "tag:Name": "{{ instance_name }}"
      register: ec2_facts

    - debug: var=ec2_facts

    - name: add hosts to groups
      add_host:
        name: "{{ item.id }}"
        ansible_ssh_host: "{{ item.public_dns_name }}"
        groups: started
      changed_when: false
      with_items: ec2_facts.instances

- name: base setup
  hosts: started
  gather_facts: no
  vars_files:
    - vars/dev.yml
  user: ec2-user
  roles:
    - base
  tags:
    - base

Minha pergunta: as jogadas estão funcionando, mas existe uma maneira melhor de fazer isso? Por exemplo, tenho gather_facts: no seguido por ec2_remote_facts e filters - tudo parece bastante complicado.

Um esclarecimento: obrigado pelo comentário sobre ec2.py - Eu já estou usando no meu primeiro jogo (quando eu chamo o papel provision ).

Mas, para fins de teste, quero saltar para as execuções subsequentes sem refazer o provisionamento (lento). Então, como repovoar meus dados de hosts? ec2_remote_facts seguido por add_host é o caminho certo? Ou posso de alguma forma usar gather_facts: yes ?

    
por Sonia Hamilton 18.12.2015 / 02:58

3 respostas

6

Eu provavelmente usaria o script de inventário dinâmico EC2, que você pode usar configurando ec2.ini e passando -i ec2.py para ansible-playbook .

Veja link para mais informações.

Observe que há muitas opções em ec2.ini . Não deixe de dar uma olhada naqueles, por exemplo %código%. Você também pode tornar a geração de inventário mais rápida, filtrando recursos desnecessários (por exemplo, defina cache_max_age se você estiver interessado apenas em instâncias do EC2).

ATUALIZAÇÃO: Com o Ansible 2.x + você também pode usar rds = False mid-play.

    
por 19.12.2015 / 19:25
2

Embora o meta: refresh_inventory seja o "método preferido", tenho a tendência de gostar da proposta do OP de usar ec2_remote_facts em conjunto com add_host . Eu configurei um tal manual e ele tem a força para ser 100% dinâmico sem falhas de cache.

Assumindo que suas instâncias de ASG dispararam com a tag env: cool_asg_instance , adicione o seguinte abaixo da chamada% play_bookbook:

- ec2_remote_facts:
    filters:
      "tag:env": "cool_asg_instance"
  register: instance_facts

Você então reunirá um conjunto de dados JSON completo contendo todas as informações necessárias, a partir de onde você pode usar os recursos ec2_asg no playbook para extrair endereços IP recém-criados, por exemplo:

- name: group hosts
  add_host: hostname={{ item }} groups=launched
  with_items: "{{ instance_facts.instances|selectattr('state', 'equalto', 'running')|map(attribute='private_ip_address')|list }}"

O filtro é cortesia desta postagem no blog: link

De agora em diante, você pode usar o grupo Jinja2 em seu arquivo YAML de implantação pai assim:

- hosts: launched
  gather_facts: no

  tasks: 
    - name: wait for SSH
      wait_for: port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH delay=5

Alguns podem perguntar por que a dor de cabeça, bem, imagine que, em vez de ter um launched hediondo que irá userdata Ansible e um manual da Internet, você pode acionar a configuração da instância de seu próprio centro de implantação configurando um simples SNS tópico que será publicado em uma fila SQS , assistido por um código python de 10 linhas ( link ) que acionará o Ansible quando uma nova instância for lançada.

    
por 06.08.2016 / 09:10
0

Eu achei que isso foi mais fácil do que eu esperava. O código a seguir permite que você execute os livros didáticos em relação ao inventário existente da AWS, que é o que eu originalmente quero fazer. Baseado em [1] e [2].

(minha solução é um pouco mais flexível, por exemplo, personalizada ansible.cfg & ssh_config )

Configure um arquivo de configuração ansioso e use-o:

% cat ./ansible.cfg.foo
[defaults]
hostfile = inventory
host_key_checking = false
private_key_file = bar.pem
remote_user = ec2-user
ssh_args = -F ./ssh_config

export ANSIBLE_CONFIG=ansible.cfg.foo

Opcionalmente, configure o ssh config personalizado, para que as configurações do seu laptop não interfiram. ssh config também pode ser feito em ansible.cfg.foo , mas eu gosto de separá-lo para que um ~/.ssh/config existente possa ser usado por terceiros.

% cat ./ssh_config
StrictHostKeyChecking no
...

Execute o seu manual:

ansible-playbook config.yml --tags base

Onde o manual pode ser semelhante ao seguinte. Tags aws (por exemplo, tag_env_test ) são usadas para selecionar hosts.

% cat config.yml
- name: base setup
  hosts:
    - tag_env_test
  become: true
  vars_files:
    - vars/qux.yml
  roles:
    - base
  tags:
    - base

- name:  java setup
  hosts:
  ...

Eu uso ./ec2.py --list > ../ec2_output.txt para investigar os hosts que eu estou interessado em selecionar.

Eu marquei a resposta de Jukka como a solução, para agradecer a ele por ajudar: -)

[1] link

[2] link

    
por 05.01.2016 / 02:04