List all my hetzner server names and their IPv4 addresses - getting error - deployment

I'm trying to receive a list of all my server names and their IPs on Hetzner using ansible and hcloud module however I'm receiving the following error;
ERROR! couldn't resolve module/action 'hcloud'. This often indicates a misspelling, missing collection, or incorrect module path.
The error appears to be in '/home/melvmagr/repos/ansible/server-content/server-content.yml': line 8, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: List servers
^ here
Here is my YAML file;
---
- name: List Hetzner server names and IP addresses
hosts: servername_example
gather_facts: false
vars:
hcloud_token: "MY_HETZNER_API_TOKEN"
tasks:
- name: List servers
hcloud:
api_token: "MY_HETZNER_API_TOKEN"
state: present
command: server_list
register: server_list
- name: Print server names and IP addresses
debug:
msg: "Server {{ item.name }} has IP address {{ item.public_net.ipv4.ip }}"
loop: "{{ server_list.servers }}"
More info that could prove to be helpful:
❯ ansible --version
ansible [core 2.12.10]
config file = /home/melvmagr/repos/ansible/ansible.cfg
configured module search path = ['/home/melvmagr/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /home/melvmagr/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.8.10 (default, Nov 14 2022, 12:59:47) [GCC 9.4.0]
jinja version = 2.10.1
libyaml = True
This is my ansible.cfg file;
[defaults]
inventory=./inventories
host_key_checking = False
log_path=/var/tmp/ansible_history
timeout=300
I've also installed the following collections;
ansible-galaxy collection install hetzner.hcloud
❯ ls ~/.ansible/collections/ansible_collections/hetzner/hcloud/
CHANGELOG.rst COPYING FILES.json MANIFEST.json README.md changelogs meta plugins tests
Any help would be greatly appreciated. Thank you!

Managed to solve it by simplifying my playbook the following way;
---
- name: Get server information from Hetzner Cloud
hosts: myservername
gather_facts: false
tasks:
- name: Print server names and IP addresses
debug:
msg: "{{ inventory_hostname }} IP is {{ ansible_ssh_host }}"

Related

Saltstack Config job returns "The minion has not yet returned"

I am new to saltstack and I am trying to run a job using the SaltStack Config.
I have a master and minion(Windows machine).
the init.sls file is the following:
{% set machineName = salt['pillar.get']('machineName', '') %}
C:\\Windows\\temp\\salt\\scripts:
file.recurse:
- user: Administrator
- group: Domain Admins
- file_mode: 755
- source: salt://PROJECTNAME/DNS/scripts
- makedirs: true
run-multiple-files:
cmd.run:
- cwd: C:\\Windows\\temp\\salt\\scripts
- names:
- ./dns.bat {{ machineName }}
and the dns.bat file:
Get-DnsServerResourceRecordA -ZoneName corp.local
The main idea is to create DNS record, but for now I am trying to run only this command to check things out, but I get the following info message when I run the job:
"The minion has not yet returned. Please try again later."
I went to check out in the master and ran the command: salt-run manage.status and got the following:
salt-run manage.status
/usr/lib/python3.7/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.23) or chardet (4.0.0) doesn't match a supported version!
RequestsDependencyWarning)
down:
- machine1
- machine2
- machine3
up:
- saltmaster
I tried some commands, to restart the machines, but still no success.
Any help would be appreciated! Thanks in advance!

Ansible IP Adress from Host to Variable and use in Playbook - Save Switch Config with Ansible

I want to save the startup and running config with ansible. My script works but only on one host. I need to change the name from the save file otherwise it will overwrite the old Configuration.
---
- hosts: switches
gather_facts: yes
vars:
ansible_network_os: icx
ansible_become: True
ansible_become_method: enable
tasks:
- name: Backup Config Files
icx_command:
commands:
- copy startup-config tftp 192.168.10.5 Ansible-startup-config.cfg
- copy running-config tftp 192.168.10.5 Ansible-running-config.cfg
Now I want to have the ip address, time and date in the name so that they will not be overwritten when I start the script again.
I think about something like this as filename:
192.168.9.13-2021-04-08-18:25-startup-config.cfg
or an consecutive number
How can I do this?
The rough idea below.
I'm not 100% sure facts gathered on ios populate ansible_default_ipv4. You will have to check that point and find the correct variable if needed. Note also you may have to run explicitly the icx_facts module to get all the info from your device.
You can run the following ad-hoc commands to browse all available facts and choose the correct one if ever:
ansible -i your_inventory some_host -m setup
ansible -i your_inventory some_host -m icx_facts
You can debug the ansible_date_time variable to see if an other key suits your needs better than below to create a time stamp. I reconstructed exactly the pattern in your question.
Of course, you need to gather facts for these vars to be available (gather_facts: true on your play meets that requirement).
And here is the sample task (untested, I don't have an ios device available for that)
- name: Backup Config Files
vars:
ip: "{{ ansible_default_ipv4.address }}"
stamp: "{{ ansible_date_time.date }}-{{ ansible_date_time.hour }}:{{ ansible_date_time.minute }}"
prefix: "{{ ip }}-{{ stamp }}"
icx_command:
commands:
- "copy startup-config tftp 192.168.10.5 {{ prefix }}-startup-config.cfg"
- "copy running-config tftp 192.168.10.5 {{ prefix }}-running-config.cfg"

Using Jinja template "ssh-rsa {{ v1.public_ssh_keys }}" in cloud-config gives a warning "Could not find supported sub-handler for type text/jinja2"

I've started to use cloud-config to initialize my Ubuntu 16.04 VM instances on Cloudstack.
In my cloud-config, I'm trying to use the public key of a key pair created in Cloudstack with this Jinja template :
## template: jinja
#cloud-config
cloud_init_modules:
- users-groups
users:
- default
- name: xyz
ssh-authorized-keys:
- ssh-rsa {{ v1.public_ssh_keys }}
sudo: ['ALL=(ALL) NOPASSWD:ALL']
groups: sudo
shell: /bin/bash
I receive the following error message :
2019-07-16 19:27:35,737 - jinja_template.py[WARNING]: Ignoring jinja template for part-001. Could not find supported sub-handler for type text/jinja2
No 'init' modules to run under section 'cloud_init_modules'
The key is however correctly passed in the instance data :
# cloud-init query v1.public_ssh_keys
[
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0EyQVA+A+CnrVBo7psi4XuZIbS6Zxq3JtiJK/wCZoPB3vKdvtDtwYkrFf1gBg4rzLDJiTTbbYZaPDa0IP82jdwSBBTzjJbF9mbeJfG70DbWqgzxzU40/fJibD1GqsEmFGh9jDAyyGLDuYo5o6LEprr3n6WIDbcsIlZFSr648RhpvTT8RmAcBj26/fkLsG2lSsQlNkWelSFj4kTn5FRcEbFb1QwwAwMza4gCqz4x3pmoqB/tSc81YRVDosik972j3+Np7Unz16PBbe6Sri5JYZaT5muS7baY9M87Nu/cOKZkr6kkxpGTHIKv6tW71f/CQVcTLEz9IG55xghAjVq9Kv"
]
I've tried with the package python-jinja2 installed (apt-get install -y python-jinja2) but it doesn't fix my issue.

Ansible passing variables between host contexts

As the title says when I'd like to be able to pass a variable that is registered under one host group to another, but I'm not sure how to do that and I couldn't find anything relevant under the variable documentation http://docs.ansible.com/ansible/playbooks_variables.html
This is a simplified example of what I am trying to see. I have a playbook that calls many different groups and checks where a symlink points. I'd like to be able to report all of the symlink targets to console at the end of the play.
The problem is the registered value is only valid under the host group that it was defined in. Is there a proper way of exporting these variables?
---
- hosts: max_logger
tasks:
- shell: ls -la /home/ubuntu/apps/max-logger/active | awk -F':' '{print $NF}'
register: max_logger_old_active
- hosts: max_data
tasks:
- shell: ls -la /home/ubuntu/apps/max-data/active | awk -F':' '{print $NF}'
register: max_data_old_active
- hosts: "localhost"
tasks:
- debug: >
msg="The old max_logger build is {{ max_logger_old_active.stdout }}
The old max_data build is {{ max_data_old_active.stdout }}"
You don't need to pass anything here (you just need to access). Registered variables are stored as host facts and they are stored in memory for the time the whole playbook is run, so you can access them from all subsequent plays.
This can be achieved using magic variable hostvars.
You need however to refer to a host name, which doesn't necessarily match the host group name (e.g. max_logger) which you posted in the question:
- hosts: "localhost"
tasks:
- debug: >
msg="The old max_logger build is {{ hostvars['max_logger_host'].max_logger_old_active.stdout }}
The old max_data build is {{ hostvars['max_data_host'].max_data_old_active.stdout }}"
You can also write hostvars['max_data_host']['max_data_old_active']['stdout'].

Copy file to ansible host with custom variables substituted

I'm working on an ansible-playbook which should help to generate build agents for a continuous delivery pipeline. Among other issues, I'll need to install an oracle client on such an agent. I want to do something like
- name: "Provide response file"
copy: src=/custom.rsp dest=/opt/oracle
Within the custom.rsp file I've got some variables to be substituted. Normally, one could do it with a separate shell command like this:
- name: "Substitute Vars"
shell: "sed 's|<PARAMETER>|<VALUE>|g' -i /opt/oracle/custom.rsp"
I don't like it, though. There should be a more convinient way to do this. Anybody giving me a hint?
You want to be using a template rather than copying a static file.
Also, when using the copy or template modules, the dest parameter is a full path AND filename, not just a path. So if you want to end up with a copy of custom.rsp in the directory /opt/oracle then you need to do this:
- name: "Provide response file"
template: src=/custom.rsp dest=/opt/oracle/custom.rsp
I'm going to extend Bruce's answer with an example:
This is part of my inventory.yaml:
kafka_stage:
children:
kafka_with_zookeeper_stage:
kafka_only_stage:
vars:
zookeeper_hosts: "kafka-stage01:2181,kafka-stage02:2181,kafka-stage03:2181"
kafka_with_zookeeper_stage:
hosts:
kafka-stage01:
broker_id: 0
kafka-stage02:
broker_id: 1
vars:
services:
kafka:
zookeeper:
This is part of a configuration file:
# The id of the broker. This must be set to a unique integer for each broker.
broker.id={{ broker_id }}
# {{ zookeeper_hosts }}
advertised.listeners=PLAINTEXT://{{ ansible_host }}:9092
# {{ services }}
This command in a playbook:
- name: Copy to Host
ansible.builtin.template:
src: my_configfile.properties
dest: /tmp/hejsan.properties
Gave me this on the remote host kafka-stage02:
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=1
# kafka-stage01:2181,kafka-stage02:2181,kafka-stage03:2181
advertised.listeners=PLAINTEXT://kafka-stage02:9092
# {'kafka': None, 'zookeeper': None}