Ansible und erneutes Laden von AWS Dynamic Inventory

7

Siehe auch: /programming/29003420/reload-ansibles-dynamic-inventory .

Meine Frage: Gibt es eine bessere Möglichkeit, das zu tun, was unten steht?

Ich habe eine ansible Rolle, die AWS-Maschinen bereitstellt und korrekt ausgeführt wird (beachten Sie das provisionTag):

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

Ich habe dann eine baseRolle, die ich unabhängig ausführen möchte (zum Beispiel während der Entwicklung, damit ich nicht auf die erneute Bereitstellung warten muss (beachten Sie das baseTag). Ich führe ein Spiel aus find running instances, in dem die Hosts gefiltert und gespeichert werden die Gruppe 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

Meine Frage: Die Stücke funktionieren, aber gibt es einen besseren Weg, dies zu tun? Zum Beispiel wurde ich gather_facts: noverfolgt ec2_remote_factsund das filters- alles scheint ziemlich verworren.

Eine Klarstellung: Danke für den Kommentar zu ec2.py- ich benutze ihn bereits in meinem ersten Spiel (wenn ich die provisionRolle aufrufe).

Aber zu Testzwecken möchte ich in nachfolgende Spiele springen, ohne die (langsame) Bereitstellung erneut durchzuführen. Also wie kann ich meine Rechner Daten wieder bevölkern ? Wird ec2_remote_factsgefolgt von add_hostdem richtigen Weg? Oder kann ich irgendwie verwenden gather_facts: yes?

Sonia Hamilton
quelle

Antworten:

6

Ich würde wahrscheinlich stattdessen das dynamische Inventarskript EC2 verwenden, das Sie durch Konfigurieren ec2.iniund Übergeben -i ec2.pyan verwenden können ansible-playbook.

Weitere Informationen finden Sie unter http://docs.ansible.com/ansible/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script .

Beachten Sie, dass es in viele Optionen gibt ec2.ini. Schauen Sie sich diese an, z cache_max_age. Sie können die Bestandserstellung auch beschleunigen, indem Sie unnötige Ressourcen filtern (z. B. festlegen, rds = Falsewenn Sie nur an EC2-Instanzen interessiert sind).

UPDATE: Mit Ansible 2.x + können Sie auch - meta: refresh_inventoryMid-Play verwenden.

Jukka
quelle
Warum führen Sie ein Spiel aus, um die Instanzen "programmgesteuert" zu finden, wenn Sie nur das ec2-Inventar verwenden können, um die Instanzen zu finden, z. B. anhand von Tags? Beachten Sie die erwähnte Cache-Eigenschaft. Sie können den Wert auf Null setzen, um für jeden Lauf ein neues Inventar zu erhalten (wenn Sie beim ersten Bereitstellungslauf ein leeres Inventar haben, da die Instanzen zu Beginn des Laufs noch nicht bereitgestellt wurden).
Jukka
Das versuche ich zu verstehen :-) Wie kann ich ec2.py dazu bringen, das Inventar zu füllen, wenn ich in der Mitte eines Spiels einspringe, ohne den Cache auf Null zu setzen? Verwenden Sie "collect_facts: true" und filtern Sie einfach nach den Tags?
Sonia Hamilton
1
Entweder führen Sie das zweite Stück getrennt und leere Cache in-zwischen oder ansible 2.x ist zu verwenden - meta: refresh_inventory. Wenn Sie den ec2.py-Cache leeren möchten, möchten Sie möglicherweise seine Einstellungen anpassen, um so viel wie möglich zu filtern (dh alles außer den ec2-Instanzen, an denen Sie interessiert sind), um ihn schneller zu machen.
Jukka
1
Fantastisch, danke @jukka. Ich wusste nichts davon meta: refresh_inventory.
Sonia Hamilton
1
Ich bin froh zu helfen und habe meine Antwort auch für zukünftige Leser aktualisiert.
Jukka
2

Während dies die meta: refresh_inventory"bevorzugte Methode" ist, mag ich den Vorschlag von OP, ec2_remote_factsin Verbindung mit zu verwenden add_host. Ich habe ein solches Playbook eingerichtet und es hat die Stärke, 100% dynamisch zu sein, ohne Störungen zwischenzuspeichern.

Angenommen, Ihre ASG hat Instanzen mit dem env: cool_asg_instanceTag ausgelöst , fügen Sie einfach Folgendes unter dem ec2_asgPlaybook-Aufruf hinzu:

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

Anschließend sammeln Sie ein vollständiges JSON- Dataset mit allen erforderlichen Informationen. Von dort aus können Sie mithilfe der Jinja2Funktionen im Playbook neu erstellte IP-Adressen extrahieren, z.

- Name: Gruppenhosts
  add_host: hostname = {{item}} groups = gestartet
  with_items: "{{instance_facts.instances | selectattr ('state', 'equalto', 'running') | map (attribute = 'private_ip_address') | list}}"

Der Filter wurde mit freundlicher Genehmigung dieses wunderbaren Blogposts erstellt: https://bonovoxly.github.io/2016-02-11-ansible-stuffs-ec2_remote_facts_instead_of_ec2_py

Von nun an können Sie die launchedGruppe in Ihrer übergeordneten YAML- Bereitstellungsdatei wie folgt verwenden:

- Hosts: gestartet
  collect_facts: nein

  Aufgaben: 
    - Name: Warten Sie auf SSH
      wait_for: port = 22 host = "{{inventar_hostname}}" search_regex = OpenSSH delay = 5

Manche fragen sich vielleicht , warum die Kopfschmerzen, gut vorstellen , dass stattdessen ein abscheuliche zu haben , userdatadas wird git clonesowohl ansible und ein Textbuch aus dem Internet, die Instanz - Setup von Ihrer eigenen Einsatzzentrale eines einfachen durch die Einrichtung auslösen kann SNS Thema , das zu einem veröffentlichen SQS Warteschlange, die von einem 10-zeiligen Python-Code ( https://github.com/alexandregama/python-sqs-consumer/blob/master/sqs-message-consumer-polling.py ) überwacht wird, der Ansible auslöst, wenn eine neue Instanz herauskommt .

iMil
quelle
Nur bestätigen - Wenn Sie " ASG " sagen , beziehen Sie sich auf eine AWS Auto-Scaling-Gruppe , richtig?
Blong
1
Ja, ASG ist eine Abkürzung für Auto Scaling Group
iMil
0

Ich fand das einfacher als ich erwartet hatte. Mit dem folgenden Code können Sie Playbooks für vorhandenes AWS-Inventar ausführen, was ich ursprünglich tun wollte. Basierend auf [1] und [2].

(Meine Lösung ist etwas flexibler, zB benutzerdefinierte ansible.cfg& ssh_config)

Richten Sie eine ansible-Konfigurationsdatei ein und verwenden Sie sie:

% 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

Richten Sie optional eine benutzerdefinierte SSH-Konfiguration ein, damit die Einstellungen Ihres Laptops nicht beeinträchtigt werden. ssh config könnte auch in durchgeführt werden ansible.cfg.foo, aber ich mag es, wenn es separat ist, damit ein vorhandenes ~/.ssh/configvon Dritten verwendet werden kann.

% cat ./ssh_config
StrictHostKeyChecking no
...

Führen Sie Ihr Spielbuch aus:

ansible-playbook config.yml --tags base

Wo das Playbook wie folgt aussehen könnte. aws-Tags (z. B. tag_env_test) werden zur Auswahl von Hosts verwendet.

% 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:
  ...

Ich ./ec2.py --list > ../ec2_output.txtuntersuche Hosts, die ich auswählen möchte.

Ich habe Jukkas Antwort als Lösung markiert, um ihm für seine Hilfe zu danken :-)

[1] http://www.slideshare.net/bfschott/using-ansible-dynamic-inventory-with-amazon-ec2

[2] https://aws.amazon.com/blogs/apn/getting-started-with-ansible-and-dynamic-amazon-ec2-inventory-management/

Sonia Hamilton
quelle