How to Create a New Host in Foreman with Ansible
Okay…this one was quite difficult to find online. Seems like the ansible documentation for the foreman module was seriously lacking or not kept up to date by anyone. I searched for awhile to see if anyone had an actual working model of it.
Not even in the ansible chat rooms did anyone know….which was weak.
So I spent some time getting this to work smoothly, and you will probably not find anywhere else on the web on how to do this. If you do show me….so I can kick myself.
Lets get dangerous then. 😊
Step by step:
Foreman – Already setup and your “computer resource” is hooked in (VMware)
Note: The compute profile(vmware) when hooked in, will also trigger a new vm creation in vsphere prepped to do DHCP. You can combine variables from vmware_guest module and this module as they require similar variables to be passed. To setup a one stop shop to deploy in foreman and vmware with just using ansible. Iv done this already…..
Special notes: The foreman I had setup did not have organisation or location configured. This caused the module to not function properly and I had to contact one of the developers who helped me patch the code so I didn’t require them to be configured or defined. Which I will show you all how to do.
Ansible – Assuming you have it setup and working with python 2.7 not sure this module will work with python 3. Havent tried that yet…..
Module – TheForeman Collection
Note: You can find the locations of these certs on foreman server. You will to copy them over to ansible for the callback to work properly. However, it is not needed to complete the host creation, you likely just see an error at the end of the play.
[callback_foreman]
url = ‘http://foreman-1.tdr.corp-apps.com’
ssl_cert = /etc/foreman-proxy/ssl-cert.pem
ssl_key = /etc/foreman-proxy/ssl-pvt.pem
verify_certs = /etc/foreman-proxy/ssl-ca
Okay once installed you. If you look at the ansible documentation on how to manage hosts using this module…from redhat.
It utterly useless…and will not work if you try to use the examples below.
https://people.redhat.com/evgeni/fam-antsibull/plugins/host_module.html
– name: “Create a host”
host:
username: “admin”
password: “changeme“
server_url: “https://foreman.example.com”
name: “new_host“
hostgroup: my_hostgroup
state: present
The fix was to avoid trying to touch a specific resource that is only available when you have Org/Loc enabled.
diff –git plugins/module_utils/foreman_helper.py plugins/module_utils/foreman_helper.py
index 432c76df..c9a3abda 100644
— plugins/module_utils/foreman_helper.py
+++ plugins/module_utils/foreman_helper.py
@@ -396,8 +396,9 @@ class ForemanAnsibleModule(AnsibleModule):
_host_update = next(x for x in _host_methods if x[‘name’] == ‘update’)
for param in [‘location_id‘, ‘organization_id‘]:
– _host_update_taxonomy_param = next(x for x in _host_update[‘params’] if x[‘name’] == param)
– _host_update[‘params’].remove(_host_update_taxonomy_param)
+ _host_update_taxonomy_param = next((x for x in _host_update[‘params’] if x[‘name’] == param), None)
+ if _host_update_taxonomy_param is not None:
+ _host_update[‘params’].remove(_host_update_taxonomy_param)
@_check_patch_needed(fixed_version=’2.0.0′)
def _patch_templates_resource_name(self):
Trick: with ansible you can write some of the code and run the playbook and if there are missing variables it will tell you what they are.
fatal: [testnick1]: FAILED! => {
“changed”: false,
“invocation”: {
“module_args“: {
“activation_keys“: null,
“architecture”: null,
“build”: null,
“comment”: null,
“compute_attributes“: null,
“compute_profile“: null,
“compute_resource“: null,
“config_groups“: null,
“content_source“: null,
“content_view“: null,
“domain”: null,
“enabled”: null,
“environment”: null,
“hostgroup“: “my_hostgroup“,
“image”: null,
“interfaces_attributes“: null,
“ip“: null,
“kickstart_repository“: null,
“lifecycle_environment“: null,
“location”: null,
“mac”: null,
“managed”: null,
“medium”: null,
“name”: “testnick1”,
“openscap_proxy“: null,
“operatingsystem“: null,
“organization”: null,
“owner”: null,
“owner_group“: null,
“parameters”: null,
“password”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,
“provision_method“: null,
“ptable“: null,
“puppet_ca_proxy“: null,
“puppet_proxy“: null,
“puppetclasses“: null,
“pxe_loader“: null,
“realm”: null,
“root_pass“: null,
“server_url“: “http://foreman-1.nictailor.com/”,
“state”: “present”,
“subnet”: null,
“subnet6”: null,
“username”: “ntailor“,
“validate_certs“: true
}
},
“msg“: “The hostname must be FQDN”
}
PLAY RECAP ************************************************************************************************************************************************************************
testnick1 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Create a Host: This code is what you need for this module to work.
– name: “Create a host”
theforeman.foreman.host:
username: “{{ foreman_user }}”
password: “{{ vcenter_password }}”
server_url: “{{ server_url }}”
name: “{{ inventory_hostname }}”
hostgroup: “{{ host_group }}”
managed: no
build: no
compute_profile: “{{ compute_profile }}”
compute_resource: “{{ computer_resource }}”
compute_attributes:
cpus: “{{ vm_cpu_count }}”
memory_mb: “{{ vm_memory }}”
interfaces_attributes:
– type: “interface”
primary: true
compute_attributes:
name: nic1
network: “{{ vm_vlan_name }}”
interface: “{{ vm_interface }}”
subnet: “{{ vm_subnet }}”
ip: “{{ vm_ip }}”
domain: “{{ domain }}”
provision: yes
operatingsystem: “{{ operating_system }}”
medium: “{{ medium }}”
architecture: x86_64
pxe_loader: PXELinux BIOS
puppet_ca_proxy: “{{ puppet_ca_proxy }}”
puppet_proxy: “{{ puppet_proxy }}”
root_pass: “{{ root_pass }}”
environment: tdr
# ptable: Centos – LVM – / , swap
ptable: “{{ ptable }}”
# owner: unix
state: present
validate_certs: false
delegate_to: localhost
– name: “Switch host on”
theforeman.foreman.host_power:
username: “{{ foreman_user }}”
password: “{{ foreman_password }}”
server_url: “{{ server_url }}”
hostname: “{{ inventory_hostname }}”
state: on
validate_certs: false
delegate_to: localhost
Note: You can find all these variables inside foreman GUI with a bit of digging.
foreman_user: Reptilianfilth
foreman_password: { generally want a ansible vault password }
compute_profile: vmware
computer_resource: vcenter.nic.internal
domain: nic.internal
medium: 7.8-CentOS
puppet_ca_proxy: puppet-2.nic.internal
puppet_proxy: puppet-2.nic.internal
#VM creation variables
vm_network: niccorp-192.168.65_corp
vm_interface: VMXNET3
vm_subnet: 192.168.65.0
vm_ip: 192.168.65.103
domain: nic.internal
managed: no
host_group: Base-Server/Centos-7.8.2003
operating_system: Centos 7.8.2003
ptable: Centos – LVM – / , swap
root_pass: changemetwiceaday
medium: 7.8-CentOS
Special Note: Now if you wanted to have it so you can use foreman module or vmware_guest module combining the variables names between the modules.
You can do as below. You will need to ensure the variables match but it works. You can get around having to rely on DHCP with this.
#VM creation variables foreman and vmware together
vm_vlan_name: nic_192.168.44_db_stor2
vm_datastore: esx_nicrcorp
vm_dvswitch: VDS-nic-Corporate
vm_interface: VMXNET3
vm_subnet: 192.1268.44.0
vm_ip: 192.168.44.14
vm_netmask: 255.255.255.0
vm_gateway: 192.168.44.254
vm_dns_servers: [192.168.1.1]
vm_dns_suffix: nic.internal
vm_cpu_count: 4
vm_memory: 16384
vm_state: poweredon
vm_connected: true
domain: tdr.internal
managed: no
host_group: Base-Server/Centos-7.8.2003
operating_system: Centos 7.8.2003
ptable: Centos – LVM – / , swap
root_pass: changemetwiceaday
medium: 7.8-CentOS
Before you to start one last thing. If you remember in the defaults we outlined
compute_profile: vmware
(this is the foreman profile it will use, so whatever defaults you have set for network and disksize here is what will be used to trigger foreman to create a host in vcenter, so it good to go check this in foreman first.)
Run playbook: from /etc/ansible
[root@nick ansible]# ansible-playbook –i inventory/TDR/hosts foremancreatehost.yml –ask-vault-pass –limit ‘testnick3.tdr.internal’
Vault password:
PLAY [all] **********************************************************************************************************************************************
TASK [ansible-provision-foreman : Create a host] ********************************************************************************************************
changed: [testnick3.tdr.internal]
PLAY RECAP *******************************************************************************************************************************************************************************
testnick3.tdr.internal : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
403 Client Error: Forbidden for url: http://foreman-1.nic.corp.com/api/v2/reports (if you see this, just ignore it) Its just callback report.