This guide installs and bootstraps a FreeIPA server instance using Ansible. FreeIPA 4.13.1 includes Modern WebUI beta, DNS over TLS/HTTPS support, and LDAP system accounts.
ipa-server-install with DNS supportBefore running the playbook, ensure:
---
- name: Install FreeIPA on Debian family
hosts: freeipa_debian
become: true
vars:
ipa_domain: example.com
ipa_realm: EXAMPLE.COM
ipa_hostname: ipa.example.com
ipa_ds_password: "{{ vault_ipa_ds_password }}"
ipa_admin_password: "{{ vault_ipa_admin_password }}"
ipa_setup_dns: true
ipa_forwarder: "8.8.8.8"
pre_tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
changed_when: false
tasks:
# System preparation
- name: Set hostname
ansible.builtin.hostname:
name: "{{ ipa_hostname }}"
- name: Update /etc/hosts with hostname
ansible.builtin.lineinfile:
path: /etc/hosts
line: "127.0.0.1 {{ ipa_hostname }}"
insertafter: EOF
- name: Install NTP client
ansible.builtin.apt:
name: chrony
state: present
- name: Start and enable NTP
ansible.builtin.systemd:
name: chrony
state: started
enabled: true
# Install FreeIPA packages
- name: Install FreeIPA packages
ansible.builtin.apt:
name:
- freeipa-server
- freeipa-server-dns
- bind9utils # for nslookup/dig
state: present
update_cache: true
# Run unattended FreeIPA installation
- name: Run unattended FreeIPA installation
ansible.builtin.command: >
ipa-server-install
--unattended
--hostname={{ ipa_hostname }}
--domain={{ ipa_domain }}
--realm={{ ipa_realm }}
--ds-password={{ ipa_ds_password }}
--admin-password={{ ipa_admin_password }}
{% if ipa_setup_dns %}
--setup-dns
--forwarder={{ ipa_forwarder }}
--auto-forwarders
{% endif %}
args:
creates: /etc/ipa/default.conf
register: ipa_install_result
# Verify installation
- name: Ensure IPA service is active
ansible.builtin.command: ipactl status
changed_when: false
register: ipa_status
- name: Display IPA status
ansible.builtin.debug:
msg: "{{ ipa_status.stdout_lines }}"
# Configure version-specific features (4.13.x+)
- name: Enable FAST armor (4.13.x+)
ansible.builtin.command: ipa config-mod --enable-fast-armor=True
changed_when: true
when: ipa_install_result.rc == 0
- name: Install FreeIPA on RHEL family
hosts: freeipa_rhel
become: true
vars:
ipa_domain: example.com
ipa_realm: EXAMPLE.COM
ipa_hostname: ipa.example.com
ipa_ds_password: "{{ vault_ipa_ds_password }}"
ipa_admin_password: "{{ vault_ipa_admin_password }}"
ipa_setup_dns: true
ipa_forwarder: "8.8.8.8"
pre_tasks:
- name: Update package cache
ansible.builtin.dnf:
update_cache: true
changed_when: false
tasks:
# System preparation
- name: Set hostname
ansible.builtin.hostname:
name: "{{ ipa_hostname }}"
- name: Update /etc/hosts with hostname
ansible.builtin.lineinfile:
path: /etc/hosts
line: "127.0.0.1 {{ ipa_hostname }}"
insertafter: EOF
- name: Install NTP client
ansible.builtin.dnf:
name: chrony
state: present
- name: Start and enable NTP
ansible.builtin.systemd:
name: chrony
state: started
enabled: true
# Install FreeIPA packages
- name: Install FreeIPA packages
ansible.builtin.dnf:
name:
- freeipa-server
- freeipa-server-dns
- bind-dyndb-ldap # DNS plugin
state: present
# Run unattended FreeIPA installation
- name: Run unattended FreeIPA installation
ansible.builtin.command: >
ipa-server-install
--unattended
--hostname={{ ipa_hostname }}
--domain={{ ipa_domain }}
--realm={{ ipa_realm }}
--ds-password={{ ipa_ds_password }}
--admin-password={{ ipa_admin_password }}
{% if ipa_setup_dns %}
--setup-dns
--forwarder={{ ipa_forwarder }}
--auto-forwarders
{% endif %}
args:
creates: /etc/ipa/default.conf
register: ipa_install_result
# Verify installation
- name: Ensure IPA service is active
ansible.builtin.command: ipactl status
changed_when: false
register: ipa_status
- name: Display IPA status
ansible.builtin.debug:
msg: "{{ ipa_status.stdout_lines }}"
# Configure version-specific features (4.13.x+)
- name: Enable FAST armor (4.13.x+)
ansible.builtin.command: ipa config-mod --enable-fast-armor=True
changed_when: true
when: ipa_install_result.rc == 0
# Post-installation configuration
- name: Configure FreeIPA post-installation
hosts: freeipa_servers
become: true
tasks:
- name: Wait for IPA services to be ready
ansible.builtin.wait_for:
port: 443
host: "{{ ipa_hostname }}"
delay: 30
timeout: 300
- name: Configure default shell for new users
ansible.builtin.shell: |
export KRB5CCNAME=/tmp/krb5cc_admin
kinit -k admin
ipa config-mod --defaultshell=/bin/bash
args:
executable: /bin/bash
changed_when: true
- name: Configure session timeout
ansible.builtin.shell: |
export KRB5CCNAME=/tmp/krb5cc_admin
kinit -k admin
ipa config-mod --sessiontimeout=20
args:
executable: /bin/bash
changed_when: true
# Configure DNS over TLS (4.13.x+)
- name: Configure DNS over TLS forwarder (4.13.x+)
ansible.builtin.shell: |
export KRB5CCNAME=/tmp/krb5cc_admin
kinit -k admin
ipa dnsconfig-mod --forwarder="dot://8.8.8.8:853"
args:
executable: /bin/bash
changed_when: true
ignore_errors: true # May fail if DNS over TLS not supported
Create an inventory file inventory.ini:
[freeipa_debian]
ipa-debian ansible_host=192.168.1.100
[freeipa_rhel]
ipa-rhel ansible_host=192.168.1.101
[freeipa_servers:children]
freeipa_debian
freeipa_rhel
[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/id_rsa
Store sensitive information in an Ansible vault:
# group_vars/all/vault.yml
vault_ipa_ds_password: "SecureDirectoryManagerPassword"
vault_ipa_admin_password: "SecureAdminPassword"
# Encrypt the vault file
ansible-vault encrypt group_vars/all/vault.yml
# Run the playbook with vault password
ansible-playbook -i inventory.ini --ask-vault-pass freeipa-install.yml
# Or with password file
ansible-playbook -i inventory.ini --vault-password-file ~/.vault_pass freeipa-install.yml
freeipa_debian groupFor more complex setups, consider using the official FreeIPA Ansible roles:
# Install the FreeIPA Ansible role
ansible-galaxy install freeipa.ansible-freeipa
Then use in your playbook:
---
- name: Install FreeIPA with official role
hosts: ipa_server
become: true
vars:
ipaadmin_password: "{{ vault_ipa_admin_password }}"
ipadm_password: "{{ vault_ipa_ds_password }}"
ipaserver_domain: example.com
ipaserver_realm: EXAMPLE.COM
ipaserver_setup_firewalld: true
ipaserver_setup_dns: true
ipaserver_auto_forwarders: true
ipaserver_auto_reverse: true
roles:
- role: freeipa.ansible-freeipa.ipaserver
The playbook includes configuration for FreeIPA 4.13.x features:
Beyond this playbook, we offer:
Contact our automation team: office@linux-server-admin.com