Automating system administration by using RHEL system roles Red Hat Enterprise Linux 9 Consistent and repeatable configuration of RHEL deployments across multiple hosts with Red Hat Ansible Automation Platform playbooks Red Hat Customer Content Services

Commands:
useradd ansible
su - ansible
[ansible@control-node]USD ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/ansible/.ssh/id_rsa): Enter passphrase (empty for no passphrase): <password> Enter same passphrase again: <password>
[defaults] inventory = /home/ansible/inventory remote_user = ansible [privilege_escalation] become = True become_method = sudo become_user = root become_ask_pass = True
managed-node-01.example.com [US] managed-node-02.example.com ansible_host=192.0.2.100 managed-node-03.example.com
dnf install rhel-system-roles
[ansible@control-node]USD ansible-galaxy collection install redhat.rhel_system_roles
useradd ansible
passwd ansible Changing password for user ansible. New password: <password> Retype new password: <password> passwd: all authentication tokens updated successfully.
[ansible@control-node]USD ssh-copy-id managed-node-01.example.com /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ansible/.ssh/id_rsa.pub" The authenticity of host 'managed-node-01.example.com (192.0.2.100)' can't be established. ECDSA key fingerprint is SHA256:9bZ33GJNODK3zbNhybokN/6Mq7hu3vpBXDrCxe7NAvo.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ansible@managed-node-01.example.com's password: <password> Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'managed-node-01.example.com'" and check to make sure that only the key(s) you wanted were added.
[ansible@control-node]USD ssh managed-node-01.example.com whoami ansible
visudo /etc/sudoers.d/ansible
ansible ALL=(ALL) ALL
ansible ALL=(ALL) NOPASSWD: ALL
[ansible@control-node]USD ansible all -m ping BECOME password: <password> managed-node-01.example.com | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" }
[ansible@control-node]USD ansible all -m command -a whoami BECOME password: <password> managed-node-01.example.com | CHANGED | rc=0 >> root
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
ansible-vault view vault.yml Vault password: <vault_password> my_secret: "yJJvPqhsiusmmPPZdnjndkdnYNDjdj782meUZcw"
ansible-vault edit vault.yml Vault password: <vault_password>
ansible-vault encrypt vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password> Encryption successful
ansible-vault decrypt vault.yml Vault password: <vault_password> Decryption successful
ansible-vault rekey vault.yml Vault password: <vault_password> New Vault password: <vault_password> Confirm New Vault password: <vault_password> Rekey successful
--- - name: Create user accounts for all servers hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Create user from vault.yml file user: name: "{{ username }}" password: "{{ pwhash }}"
--- - name: Set boot device to be used on next boot hosts: managed-node-01.example.com tasks: - name: Ensure boot device is HD redhat.rhel_mgmt.ipmi_boot: user: <admin_user> password: <password> bootdev: hd
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Power management hosts: managed-node-01.example.com tasks: - name: Ensure machine is powered on redhat.rhel_mgmt.ipmi_power: user: <admin_user> password: <password> state: on
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Manage out-of-band controllers using Redfish APIs hosts: managed-node-01.example.com tasks: - name: Get CPU inventory redhat.rhel_mgmt.redfish_info: baseuri: " <URI> " username: " <username> " password: " <password> " category: Systems command: GetCpuInventory register: result
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Manage out-of-band controllers using Redfish APIs hosts: managed-node-01.example.com tasks: - name: Power on system redhat.rhel_mgmt.redfish_command: baseuri: " <URI> " username: " <username> " password: " <password> " category: Systems command: PowerOn
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Manages out-of-band controllers using Redfish APIs hosts: managed-node-01.example.com tasks: - name: Set BootMode to UEFI redhat.rhel_mgmt.redfish_config: baseuri: " <URI> " username: " <username> " password: " <password> " category: Systems command: SetBiosAttributes bios_attributes: BootMode: Uefi
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
usr: administrator pwd: <password>
--- - name: Active Directory integration hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Join an Active Directory ansible.builtin.include_role: name: rhel-system-roles.ad_integration vars: ad_integration_user: "{{ usr }}" ad_integration_password: "{{ pwd }}" ad_integration_realm: "ad.example.com" ad_integration_allow_rc4_crypto: false ad_integration_timesync_source: "time_server.ad.example.com"
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'getent passwd administrator@ad.example.com' administrator@ad.example.com:*:1450400500:1450400513:Administrator:/home/administrator@ad.example.com:/bin/bash
--- - name: Configuration and management of GRUB boot loader hosts: managed-node-01.example.com tasks: - name: Update existing boot loader entries ansible.builtin.include_role: name: rhel-system-roles.bootloader vars: bootloader_settings: - kernel: path: /boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64 options: - name: quiet state: present bootloader_reboot_ok: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.command -a 'grubby --info=ALL' managed-node-01.example.com | CHANGED | rc=0 >> index=1 kernel="/boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64" args="ro crashkernel=1G-4G:256M,4G-64G:320M,64G-:576M rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap USDtuned_params quiet " root="/dev/mapper/rhel-root" initrd="/boot/initramfs-5.14.0-362.24.1.el9_3.aarch64.img USDtuned_initrd" title="Red Hat Enterprise Linux (5.14.0-362.24.1.el9_3.aarch64) 9.4 (Plow)" id="2c9ec787230141a9b087f774955795ab-5.14.0-362.24.1.el9_3.aarch64"
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
pwd: <password>
--- - name: Configuration and management of GRUB boot loader hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Set the bootloader password ansible.builtin.include_role: name: rhel-system-roles.bootloader vars: bootloader_password: "{{ pwd }}" bootloader_reboot_ok: true
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
--- - name: Configuration and management of the GRUB boot loader hosts: managed-node-01.example.com tasks: - name: Update the boot loader timeout ansible.builtin.include_role: name: rhel-system-roles.bootloader vars: bootloader_timeout: 10
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.reboot managed-node-01.example.com | CHANGED => { "changed": true, "elapsed": 21, "rebooted": true }
ansible managed-node-01.example.com -m ansible.builtin.command -a "grep 'timeout' /boot/grub2/grub.cfg" managed-node-01.example.com | CHANGED | rc=0 >> if [ xUSDfeature_timeout_style = xy ] ; then set timeout_style=menu set timeout=10 Fallback normal timeout code in case the timeout_style feature is set timeout=10 if [ xUSDfeature_timeout_style = xy ] ; then set timeout_style=menu set timeout=10 set orig_timeout_style=USD{timeout_style} set orig_timeout=USD{timeout} # timeout_style=menu + timeout=0 avoids the countdown code keypress check set timeout_style=menu set timeout=10 set timeout_style=hidden set timeout=10 if [ xUSDfeature_timeout_style = xy ]; then if [ "USD{menu_show_once_timeout}" ]; then set timeout_style=menu set timeout=10 unset menu_show_once_timeout save_env menu_show_once_timeout
--- - name: Configuration and management of GRUB boot loader hosts: managed-node-01.example.com tasks: - name: Gather information about the boot loader configuration ansible.builtin.include_role: name: rhel-system-roles.bootloader vars: bootloader_gather_facts: true - name: Display the collected boot loader configuration information debug: var: bootloader_facts
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
"bootloader_facts": [ { "args": "ro crashkernel=1G-4G:256M,4G-64G:320M,64G-:576M rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap USDtuned_params quiet", "default": true, "id": "2c9ec787230141a9b087f774955795ab-5.14.0-362.24.1.el9_3.aarch64", "index": "1", "initrd": "/boot/initramfs-5.14.0-362.24.1.el9_3.aarch64.img USDtuned_initrd", "kernel": "/boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64", "root": "/dev/mapper/rhel-root", "title": "Red Hat Enterprise Linux (5.14.0-362.24.1.el9_3.aarch64) 9.4 (Plow)" } ]
--- - name: Create certificates hosts: managed-node-01.example.com tasks: - name: Create a self-signed certificate ansible.builtin.include_role: name: rhel-system-roles.certificate vars: certificate_requests: - name: web-server ca: ipa dns: www.example.com principal: HTTP/www.example.com@EXAMPLE.COM run_before: systemctl stop httpd.service run_after: systemctl start httpd.service
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'getcert list' Number of certificates and requests being tracked: 1. Request ID '20240918142211': status: MONITORING stuck: no key pair storage: type=FILE,location='/etc/pki/tls/private/web-server.key' certificate: type=FILE,location='/etc/pki/tls/certs/web-server.crt' CA: IPA issuer: CN=Certificate Authority,O=EXAMPLE.COM subject: CN=www.example.com issued: 2024-09-18 16:22:11 CEST expires: 2025-09-18 16:22:10 CEST dns: www.example.com key usage: digitalSignature,keyEncipherment eku: id-kp-serverAuth,id-kp-clientAuth pre-save command: systemctl stop httpd.service post-save command: systemctl start httpd.service track: yes auto-renew: yes
--- - name: Create certificates hosts: managed-node-01.example.com tasks: - name: Create a self-signed certificate ansible.builtin.include_role: name: rhel-system-roles.certificate vars: certificate_requests: - name: web-server ca: self-sign dns: test.example.com
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'getcert list' Number of certificates and requests being tracked: 1. Request ID '20240918133610': status: MONITORING stuck: no key pair storage: type=FILE,location='/etc/pki/tls/private/web-server.key' certificate: type=FILE,location='/etc/pki/tls/certs/web-server.crt' CA: local issuer: CN=c32b16d7-5b1a4c5a-a953a711-c3ca58fb,CN=Local Signing Authority subject: CN=test.example.com issued: 2024-09-18 15:36:10 CEST expires: 2025-09-18 15:36:09 CEST dns: test.example.com key usage: digitalSignature,keyEncipherment eku: id-kp-serverAuth,id-kp-clientAuth pre-save command: post-save command: track: yes auto-renew: yes
--- - name: Manage the RHEL web console hosts: managed-node-01.example.com tasks: - name: Install RHEL web console ansible.builtin.include_role: name: rhel-system-roles.cockpit vars: cockpit_packages: default cockpit_port: 9050 cockpit_manage_selinux: true cockpit_manage_firewall: true cockpit_certificates: - name: /etc/cockpit/ws-certs.d/01-certificate dns: ['localhost', 'www.example.com'] ca: ipa
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Configure cryptographic policies hosts: managed-node-01.example.com tasks: - name: Configure the FUTURE cryptographic security policy on the managed node ansible.builtin.include_role: name: rhel-system-roles.crypto_policies vars: - crypto_policies_policy: FUTURE - crypto_policies_reboot_ok: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Verification hosts: managed-node-01.example.com tasks: - name: Verify active cryptographic policy ansible.builtin.include_role: name: rhel-system-roles.crypto_policies - name: Display the currently active cryptographic policy ansible.builtin.debug: var: crypto_policies_active
ansible-playbook --syntax-check ~/verify_playbook.yml
ansible-playbook ~/verify_playbook.yml TASK [debug] ************************** ok: [host] => { "crypto_policies_active": "FUTURE" }
--- - name: Configuring fapolicyd hosts: managed-node-01.example.com tasks: - name: Allow only executables installed from RPM database and specific files ansible.builtin.include_role: name: rhel-system-roles.fapolicyd vars: fapolicyd_setup_permissive: false fapolicyd_setup_integrity: sha256 fapolicyd_setup_trust: rpmdb,file fapolicyd_add_trusted_file: - <path_to_allowed_command> - <path_to_allowed_service>
ansible-playbook ~/playbook.yml --syntax-check
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'su -c "/bin/not_authorized_application " <user_name> ' bash: line 1: /bin/not_authorized_application: Operation not permitted non-zero return code
--- - name: Reset firewalld example hosts: managed-node-01.example.com tasks: - name: Reset firewalld ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - previous: replaced
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-all-zones'
--- - name: Configure firewalld hosts: managed-node-01.example.com tasks: - name: Forward incoming traffic on port 8080 to 443 ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - forward_port: 8080/tcp;443; state: enabled runtime: true permanent: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-forward-ports' managed-node-01.example.com | CHANGED | rc=0 >> port=8080:proto=tcp:toport=443:toaddr=
--- - name: Configure firewalld hosts: managed-node-01.example.com tasks: - name: Creating a DMZ with access to HTTPS port and masquerading for hosts in DMZ ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - zone: dmz interface: enp1s0 service: https state: enabled runtime: true permanent: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --zone=dmz --list-all' managed-node-01.example.com | CHANGED | rc=0 >> dmz (active) target: default icmp-block-inversion: no interfaces: enp1s0 sources: services: https ssh ports: protocols: forward: no masquerade: no forward-ports: source-ports: icmp-blocks:
- hosts: node1 node2 vars: ha_cluster_cluster_present: false roles: - rhel-system-roles.ha_cluster
ha_cluster_pcs_permission_list: - type: group name: hacluster allow_list: - grant - read - write
ha_cluster_transport: type: knet options: - name: option1_name value: option1_value - name: option2_name value: option2_value links: - - name: option1_name value: option1_value - name: option2_name value: option2_value - - name: option1_name value: option1_value - name: option2_name value: option2_value compression: - name: option1_name value: option1_value - name: option2_name value: option2_value crypto: - name: option1_name value: option1_value - name: option2_name value: option2_value
ha_cluster_totem: options: - name: option1_name value: option1_value - name: option2_name value: option2_value
ha_cluster_quorum: options: - name: option1_name value: option1_value - name: option2_name value: option2_value device: model: string model_options: - name: option1_name value: option1_value - name: option2_name value: option2_value generic_options: - name: option1_name value: option1_value - name: option2_name value: option2_value heuristics_options: - name: option1_name value: option1_value - name: option2_name value: option2_value
ha_cluster_cluster_properties: - attrs: - name: property1_name value: property1_value - name: property2_name value: property2_value
- hosts: node1 node2 vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: password ha_cluster_cluster_properties: - attrs: - name: stonith-enabled value: 'true' - name: no-quorum-policy value: stop roles: - rhel-system-roles.ha_cluster
ha_cluster_node_options: - node_name: node1 pcs_address: node1-address corosync_addresses: - 192.168.1.11 - 192.168.2.11 sbd_watchdog_modules: - module1 - module2 sbd_watchdog_modules_blocklist: - module3 sbd_watchdog: /dev/watchdog2 sbd_devices: - /dev/disk/by-id/000001 - /dev/disk/by-id/000002 - /dev/disk/by-id/000003 attributes: - attrs: - name: attribute1 value: value1_node1 - name: attribute2 value: value2_node1 utilization: - attrs: - name: utilization1 value: value1_node1 - name: utilization2 value: value2_node1 - node_name: node2 pcs_address: node2-address:2224 corosync_addresses: - 192.168.1.12 - 192.168.2.12 sbd_watchdog_modules: - module1 sbd_watchdog_modules_blocklist: - module3 sbd_watchdog: /dev/watchdog1 sbd_devices: - /dev/disk/by-id/000001 - /dev/disk/by-id/000002 - /dev/disk/by-id/000003 attributes: - attrs: - name: attribute1 value: value1_node2 - name: attribute2 value: value2_node2 utilization: - attrs: - name: utilization1 value: value1_node2 - name: utilization2 value: value2_node2
- id: resource-id agent: resource-agent instance_attrs: - attrs: - name: attribute1_name value: attribute1_value - name: attribute2_name value: attribute2_value meta_attrs: - attrs: - name: meta_attribute1_name value: meta_attribute1_value - name: meta_attribute2_name value: meta_attribute2_value copy_operations_from_agent: bool operations: - action: operation1-action attrs: - name: operation1_attribute1_name value: operation1_attribute1_value - name: operation1_attribute2_name value: operation1_attribute2_value - action: operation2-action attrs: - name: operation2_attribute1_name value: operation2_attribute1_value - name: operation2_attribute2_name value: operation2_attribute2_value
ha_cluster_resource_groups: - id: group-id resource_ids: - resource1-id - resource2-id meta_attrs: - attrs: - name: group_meta_attribute1_name value: group_meta_attribute1_value - name: group_meta_attribute2_name value: group_meta_attribute2_value
ha_cluster_resource_clones: - resource_id: resource-to-be-cloned promotable: true id: custom-clone-id meta_attrs: - attrs: - name: clone_meta_attribute1_name value: clone_meta_attribute1_value - name: clone_meta_attribute2_name value: clone_meta_attribute2_value
ha_cluster_resource_defaults: meta_attrs: - id: defaults-set-1-id rule: rule-string score: score-value attrs: - name: meta_attribute1_name value: meta_attribute1_value - name: meta_attribute2_name value: meta_attribute2_value - id: defaults-set-2-id rule: rule-string score: score-value attrs: - name: meta_attribute3_name value: meta_attribute3_value - name: meta_attribute4_name value: meta_attribute4_value
ha_cluster_stonith_levels: - level: 1..9 target: node_name target_pattern: node_name_regular_expression target_attribute: node_attribute_name target_value: node_attribute_value resource_ids: - fence_device_1 - fence_device_2 - level: 1..9 target: node_name target_pattern: node_name_regular_expression target_attribute: node_attribute_name target_value: node_attribute_value resource_ids: - fence_device_1 - fence_device_2
ha_cluster_constraints_location: - resource: id: resource-id node: node-name id: constraint-id options: - name: score value: score-value - name: option-name value: option-value
ha_cluster_constraints_location: - resource: pattern: resource-pattern node: node-name id: constraint-id options: - name: score value: score-value - name: resource-discovery value: resource-discovery-value
ha_cluster_constraints_location: - resource: id: resource-id role: resource-role rule: rule-string id: constraint-id options: - name: score value: score-value - name: resource-discovery value: resource-discovery-value
ha_cluster_constraints_location: - resource: pattern: resource-pattern role: resource-role rule: rule-string id: constraint-id options: - name: score value: score-value - name: resource-discovery value: resource-discovery-value
ha_cluster_constraints_colocation: - resource_follower: id: resource-id1 role: resource-role1 resource_leader: id: resource-id2 role: resource-role2 id: constraint-id options: - name: score value: score-value - name: option-name value: option-value
ha_cluster_constraints_colocation: - resource_sets: - resource_ids: - resource-id1 - resource-id2 options: - name: option-name value: option-value id: constraint-id options: - name: score value: score-value - name: option-name value: option-value
ha_cluster_constraints_order: - resource_first: id: resource-id1 action: resource-action1 resource_then: id: resource-id2 action: resource-action2 id: constraint-id options: - name: score value: score-value - name: option-name value: option-value
ha_cluster_constraints_order: - resource_sets: - resource_ids: - resource-id1 - resource-id2 options: - name: option-name value: option-value id: constraint-id options: - name: score value: score-value - name: option-name value: option-value
ha_cluster_constraints_ticket: - resource: id: resource-id role: resource-role ticket: ticket-name id: constraint-id options: - name: loss-policy value: loss-policy-value - name: option-name value: option-value
ha_cluster_constraints_ticket: - resource_sets: - resource_ids: - resource-id1 - resource-id2 options: - name: option-name value: option-value ticket: ticket-name id: constraint-id options: - name: option-name value: option-value
ha_cluster_acls: acl_roles: - id: role-id-1 description: role description permissions: - kind: access-type xpath: XPath expression - kind: access-type reference: cib-element-id - id: role-id-2 permissions: - kind: access-type xpath: XPath expression acl_users: - id: user-name roles: - role-id-1 - role-id-2 acl_groups: - id: group-name roles: - role-id-2
ha_cluster_cluster_properties: - attrs: - name: enable-acl value: 'true'
ha_cluster_alerts: - id: alert1 path: /alert1/path description: Alert1 description instance_attrs: - attrs: - name: alert_attr1_name value: alert_attr1_value meta_attrs: - attrs: - name: alert_meta_attr1_name value: alert_meta_attr1_value recipients: - value: recipient_value id: recipient1 description: Recipient1 description instance_attrs: - attrs: - name: recipient_attr1_name value: recipient_attr1_value meta_attrs: - attrs: - name: recipient_meta_attr1_name value: recipient_meta_attr1_value
all: hosts: node1: ha_cluster: node_name: node-A pcs_address: node1-address corosync_addresses: - 192.168.1.11 - 192.168.2.11 node2: ha_cluster: node_name: node-B pcs_address: node2-address:2224 corosync_addresses: - 192.168.1.12 - 192.168.2.12
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create TLS certificates and key files in a high availability cluster ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_pcsd_certificates: - name: FILENAME common_name: "{{ ansible_hostname }}" ca: self-sign
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create cluster with minimum required parameters and no fencing ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create cluster with fencing and resources ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_resource_primitives: - id: xvm-fencing agent: 'stonith:fence_xvm' instance_attrs: - attrs: - name: pcmk_host_list value: node1 node2 - id: simple-resource agent: 'ocf:pacemaker:Dummy' - id: resource-with-options agent: 'ocf:pacemaker:Dummy' instance_attrs: - attrs: - name: fake value: fake-value - name: passwd value: passwd-value meta_attrs: - attrs: - name: target-role value: Started - name: is-managed value: 'true' operations: - action: start attrs: - name: timeout value: '30s' - action: monitor attrs: - name: timeout value: '5' - name: interval value: '1min' - id: dummy-1 agent: 'ocf:pacemaker:Dummy' - id: dummy-2 agent: 'ocf:pacemaker:Dummy' - id: dummy-3 agent: 'ocf:pacemaker:Dummy' - id: simple-clone agent: 'ocf:pacemaker:Dummy' - id: clone-with-options agent: 'ocf:pacemaker:Dummy' ha_cluster_resource_groups: - id: simple-group resource_ids: - dummy-1 - dummy-2 meta_attrs: - attrs: - name: target-role value: Started - name: is-managed value: 'true' - id: cloned-group resource_ids: - dummy-3 ha_cluster_resource_clones: - resource_id: simple-clone - resource_id: clone-with-options promotable: yes id: custom-clone-id meta_attrs: - attrs: - name: clone-max value: '2' - name: clone-node-max value: '1' - resource_id: cloned-group promotable: yes
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create cluster with fencing and resource operation defaults ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true # Set a different resource-stickiness value during # and outside work hours. This allows resources to # automatically move back to their most # preferred hosts, but at a time that # does not interfere with business activities. ha_cluster_resource_defaults: meta_attrs: - id: core-hours rule: date-spec hours=9-16 weekdays=1-5 score: 2 attrs: - name: resource-stickiness value: INFINITY - id: after-hours score: 1 attrs: - name: resource-stickiness value: 0 # Default the timeout on all 10-second-interval # monitor actions on IPaddr2 resources to 8 seconds. ha_cluster_resource_operation_defaults: meta_attrs: - rule: resource ::IPaddr2 and op monitor interval=10s score: INFINITY attrs: - name: timeout value: 8s
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password> fence1_password: <fence1_password> fence2_password: <fence2_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Configure a cluster that defines fencing levels ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_resource_primitives: - id: apc1 agent: 'stonith:fence_apc_snmp' instance_attrs: - attrs: - name: ip value: apc1.example.com - name: username value: user - name: password value: "{{ fence1_password }}" - name: pcmk_host_map value: node1:1;node2:2 - id: apc2 agent: 'stonith:fence_apc_snmp' instance_attrs: - attrs: - name: ip value: apc2.example.com - name: username value: user - name: password value: "{{ fence2_password }}" - name: pcmk_host_map value: node1:1;node2:2 # Nodes have redundant power supplies, apc1 and apc2. Cluster must # ensure that when attempting to reboot a node, both power # supplies # are turned off before either power supply is turned # back on. ha_cluster_stonith_levels: - level: 1 target: node1 resource_ids: - apc1 - apc2 - level: 1 target: node2 resource_ids: - apc1 - apc2
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create cluster with resource constraints ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true # In order to use constraints, we need resources # the constraints will apply to. ha_cluster_resource_primitives: - id: xvm-fencing agent: 'stonith:fence_xvm' instance_attrs: - attrs: - name: pcmk_host_list value: node1 node2 - id: dummy-1 agent: 'ocf:pacemaker:Dummy' - id: dummy-2 agent: 'ocf:pacemaker:Dummy' - id: dummy-3 agent: 'ocf:pacemaker:Dummy' - id: dummy-4 agent: 'ocf:pacemaker:Dummy' - id: dummy-5 agent: 'ocf:pacemaker:Dummy' - id: dummy-6 agent: 'ocf:pacemaker:Dummy' # location constraints ha_cluster_constraints_location: # resource ID and node name - resource: id: dummy-1 node: node1 options: - name: score value: 20 # resource pattern and node name - resource: pattern: dummy-\d+ node: node1 options: - name: score value: 10 # resource ID and rule - resource: id: dummy-2 rule: '#uname eq node2 and date in_range 2022-01-01 to 2022-02-28' # resource pattern and rule - resource: pattern: dummy-\d+ rule: node-type eq weekend and date-spec weekdays=6-7 # colocation constraints ha_cluster_constraints_colocation: # simple constraint - resource_leader: id: dummy-3 resource_follower: id: dummy-4 options: - name: score value: -5 # set constraint - resource_sets: - resource_ids: - dummy-1 - dummy-2 - resource_ids: - dummy-5 - dummy-6 options: - name: sequential value: "false" options: - name: score value: 20 # order constraints ha_cluster_constraints_order: # simple constraint - resource_first: id: dummy-1 resource_then: id: dummy-6 options: - name: symmetrical value: "false" # set constraint - resource_sets: - resource_ids: - dummy-1 - dummy-2 options: - name: require-all value: "false" - name: sequential value: "false" - resource_ids: - dummy-3 - resource_ids: - dummy-4 - dummy-5 options: - name: sequential value: "false" # ticket constraints ha_cluster_constraints_ticket: # simple constraint - resource: id: dummy-1 ticket: ticket1 options: - name: loss-policy value: stop # set constraint - resource_sets: - resource_ids: - dummy-3 - dummy-4 - dummy-5 ticket: ticket2 options: - name: loss-policy value: fence
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create cluster that configures Corosync values ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_transport: type: knet options: - name: ip_version value: ipv4-6 - name: link_mode value: active links: - - name: linknumber value: 1 - name: link_priority value: 5 - - name: linknumber value: 0 - name: link_priority value: 10 compression: - name: level value: 5 - name: model value: zlib crypto: - name: cipher value: none - name: hash value: none ha_cluster_totem: options: - name: block_unlisted_ips value: 'yes' - name: send_join value: 0 ha_cluster_quorum: options: - name: auto_tie_breaker value: 1 - name: wait_for_all value: 1
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Configure a cluster with ACLs assigned ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true # To use an ACL role permission reference, the reference must exist in CIB. ha_cluster_resource_primitives: - id: not-for-operator agent: 'ocf:pacemaker:Dummy' # ACLs must be enabled (using the enable-acl cluster property) in order to be effective. ha_cluster_cluster_properties: - attrs: - name: enable-acl value: 'true' ha_cluster_acls: acl_roles: - id: operator description: HA cluster operator permissions: - kind: write xpath: //crm_config//nvpair[@name='maintenance-mode'] - kind: deny reference: not-for-operator - id: administrator permissions: - kind: write xpath: /cib acl_users: - id: alice roles: - operator - administrator - id: bob roles: - administrator acl_groups: - id: admins roles: - administrator
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Configure a cluster with SBD fencing ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: my_sbd_devices: # This variable is indirectly used by various variables of the ha_cluster RHEL system role. # Its purpose is to define SBD devices once so they do not need # to be repeated several times in the role variables. - /dev/disk/by-id/000001 - /dev/disk/by-id/000002 - /dev/disk/by-id/000003 ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_sbd_enabled: true ha_cluster_sbd_options: - name: delay-start value: 'no' - name: startmode value: always - name: timeout-action value: 'flush,reboot' - name: watchdog-timeout value: 30 ha_cluster_node_options: - node_name: node1 sbd_watchdog_modules: - iTCO_wdt sbd_watchdog_modules_blocklist: - ipmi_watchdog sbd_watchdog: /dev/watchdog1 sbd_devices: "{{ my_sbd_devices }}" - node_name: node2 sbd_watchdog_modules: - iTCO_wdt sbd_watchdog_modules_blocklist: - ipmi_watchdog sbd_watchdog: /dev/watchdog1 sbd_devices: "{{ my_sbd_devices }}" # Best practice for setting SBD timeouts: # watchdog-timeout * 2 = msgwait-timeout (set automatically) # msgwait-timeout * 1.2 = stonith-timeout ha_cluster_cluster_properties: - attrs: - name: stonith-timeout value: 72 ha_cluster_resource_primitives: - id: fence_sbd agent: 'stonith:fence_sbd' instance_attrs: - attrs: - name: devices value: "{{ my_sbd_devices | join(',') }}" - name: pcmk_delay_base value: 30
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
all: hosts: node1: ha_cluster: sbd_watchdog_modules: - iTCO_wdt sbd_watchdog_modules_blocklist: - ipmi_watchdog sbd_watchdog: /dev/watchdog1 sbd_devices: - /dev/disk/by-id/000001 - /dev/disk/by-id/000001 - /dev/disk/by-id/000003 node2: ha_cluster: sbd_watchdog_modules: - iTCO_wdt sbd_watchdog_modules_blocklist: - ipmi_watchdog sbd_watchdog: /dev/watchdog1 sbd_devices: - /dev/disk/by-id/000001 - /dev/disk/by-id/000002 - /dev/disk/by-id/000003
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Configure a cluster with sbd fencing devices configured in an inventory file ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_sbd_enabled: true ha_cluster_sbd_options: - name: delay-start value: 'no' - name: startmode value: always - name: timeout-action value: 'flush,reboot' - name: watchdog-timeout value: 30 # Best practice for setting SBD timeouts: # watchdog-timeout * 2 = msgwait-timeout (set automatically) # msgwait-timeout * 1.2 = stonith-timeout ha_cluster_cluster_properties: - attrs: - name: stonith-timeout value: 72 ha_cluster_resource_primitives: - id: fence_sbd agent: 'stonith:fence_sbd' instance_attrs: - attrs: # taken from host_vars # this only works if all nodes have the same sbd_devices - name: devices value: "{{ ha_cluster.sbd_devices | join(',') }}" - name: pcmk_delay_base value: 30
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Configure a cluster with utilization attributes ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_cluster_properties: - attrs: - name: placement-strategy value: utilization ha_cluster_node_options: - node_name: node1 utilization: - attrs: - name: utilization1 value: 1 - name: utilization2 value: 2 - node_name: node2 utilization: - attrs: - name: utilization1 value: 3 - name: utilization2 value: 4 ha_cluster_resource_primitives: - id: resource1 agent: 'ocf:pacemaker:Dummy' utilization: - attrs: - name: utilization1 value: 2 - name: utilization2 value: 3
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Configure a cluster with alerts ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_alerts: - id: alert1 path: /alert1/path description: Alert1 description instance_attrs: - attrs: - name: alert_attr1_name value: alert_attr1_value meta_attrs: - attrs: - name: alert_meta_attr1_name value: alert_meta_attr1_value recipients: - value: recipient_value id: recipient1 description: Recipient1 description instance_attrs: - attrs: - name: recipient_attr1_name value: recipient_attr1_value meta_attrs: - attrs: - name: recipient_meta_attr1_name value: recipient_meta_attr1_value
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Configure a host with a quorum device hosts: nodeQ vars_files: - vault.yml tasks: - name: Create a quorum device for the cluster ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_present: false ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_qnetd: present: true
ansible-playbook --ask-vault-pass --syntax-check ~/playbook-qdevice.yml
ansible-playbook --ask-vault-pass ~/playbook-qdevice.yml
--- - name: Configure a cluster to use a quorum device hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create cluster that uses a quorum device ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_quorum: device: model: net model_options: - name: host value: nodeQ - name: algorithm value: lms
ansible-playbook --ask-vault-pass --syntax-check ~/playbook-cluster-qdevice.yml
ansible-playbook --ask-vault-pass ~/playbook-cluster-qdevice.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: node1 node2 vars_files: - vault.yml tasks: - name: Create a cluster that defines node attributes ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_cluster_name: my-new-cluster ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_node_options: - node_name: node1 attributes: - attrs: - name: attribute1 value: value1A - name: attribute2 value: value2A - node_name: node2 attributes: - attrs: - name: attribute1 value: value1B - name: attribute2 value: value2B
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
cluster_password: <cluster_password>
--- - name: Create a high availability cluster hosts: z1.example.com z2.example.com vars_files: - vault.yml tasks: - name: Configure active/passive Apache server in a high availability cluster ansible.builtin.include_role: name: rhel-system-roles.ha_cluster vars: ha_cluster_hacluster_password: "{{ cluster_password }}" ha_cluster_cluster_name: my_cluster ha_cluster_manage_firewall: true ha_cluster_manage_selinux: true ha_cluster_fence_agent_packages: - fence-agents-apc-snmp ha_cluster_resource_primitives: - id: myapc agent: stonith:fence_apc_snmp instance_attrs: - attrs: - name: ipaddr value: zapc.example.com - name: pcmk_host_map value: z1.example.com:1;z2.example.com:2 - name: login value: apc - name: passwd value: apc - id: my_lvm agent: ocf:heartbeat:LVM-activate instance_attrs: - attrs: - name: vgname value: my_vg - name: vg_access_mode value: system_id - id: my_fs agent: Filesystem instance_attrs: - attrs: - name: device value: /dev/my_vg/my_lv - name: directory value: /var/www - name: fstype value: xfs - id: VirtualIP agent: IPaddr2 instance_attrs: - attrs: - name: ip value: 198.51.100.3 - name: cidr_netmask value: 24 - id: Website agent: apache instance_attrs: - attrs: - name: configfile value: /etc/httpd/conf/httpd.conf - name: statusurl value: http://127.0.0.1/server-status ha_cluster_resource_groups: - id: apachegroup resource_ids: - my_lvm - my_fs - VirtualIP - Website
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
/usr/bin/test -f /var/run/httpd-Website.pid >/dev/null 2>/dev/null && /usr/bin/ps -q USD(/usr/bin/cat /var/run/httpd-Website.pid) >/dev/null 2>/dev/null && /usr/sbin/httpd -f /etc/httpd/conf/httpd.conf -c "PidFile /var/run/httpd-Website.pid" -k graceful > /dev/null 2>/dev/null || true
pcs status Cluster name: my_cluster Last updated: Wed Jul 31 16:38:51 2013 Last change: Wed Jul 31 16:42:14 2013 via crm_attribute on z1.example.com Stack: corosync Current DC: z2.example.com (2) - partition with quorum Version: 1.1.10-5.el7-9abe687 2 Nodes configured 6 Resources configured Online: [ z1.example.com z2.example.com ] Full list of resources: myapc (stonith:fence_apc_snmp): Started z1.example.com Resource Group: apachegroup my_lvm (ocf::heartbeat:LVM-activate): Started z1.example.com my_fs (ocf::heartbeat:Filesystem): Started z1.example.com VirtualIP (ocf::heartbeat:IPaddr2): Started z1.example.com Website (ocf::heartbeat:apache): Started z1.example.com
Hello
pcs node standby z1.example.com
pcs status Cluster name: my_cluster Last updated: Wed Jul 31 17:16:17 2013 Last change: Wed Jul 31 17:18:34 2013 via crm_attribute on z1.example.com Stack: corosync Current DC: z2.example.com (2) - partition with quorum Version: 1.1.10-5.el7-9abe687 2 Nodes configured 6 Resources configured Node z1.example.com (1): standby Online: [ z2.example.com ] Full list of resources: myapc (stonith:fence_apc_snmp): Started z1.example.com Resource Group: apachegroup my_lvm (ocf::heartbeat:LVM-activate): Started z2.example.com my_fs (ocf::heartbeat:Filesystem): Started z2.example.com VirtualIP (ocf::heartbeat:IPaddr2): Started z2.example.com Website (ocf::heartbeat:apache): Started z2.example.com
pcs node unstandby z1.example.com
--- - name: Configure journald hosts: managed-node-01.example.com tasks: - name: Configure persistent logging ansible.builtin.include_role: name: rhel-system-roles.journald vars: journald_persistent: true journald_max_disk_size: <size> journald_per_user: true journald_sync_interval: <interval>
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Configuring kernel crash dumping hosts: managed-node-01.example.com tasks: - name: Setting the kdump directory. ansible.builtin.include_role: name: rhel-system-roles.kdump vars: kdump_target: type: raw location: /dev/sda1 kdump_path: /var/crash/vmcore kernel_settings_reboot_ok: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'grep crashkernel /proc/cmdline'
--- - name: Configuring kernel settings hosts: managed-node-01.example.com tasks: - name: Configure hugepages, packet size for loopback device, and limits on simultaneously open files. ansible.builtin.include_role: name: rhel-system-roles.kernel_settings vars: kernel_settings_sysctl: - name: fs.file-max value: 400000 - name: kernel.threads-max value: 65536 kernel_settings_sysfs: - name: /sys/class/net/lo/mtu value: 65000 kernel_settings_transparent_hugepages: madvise kernel_settings_reboot_ok: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'sysctl fs.file-max kernel.threads-max net.ipv6.conf.lo.mtu' ansible managed-node-01.example.com -m command -a 'cat /sys/kernel/mm/transparent_hugepage/enabled'
--- - name: Deploy the logging solution hosts: managed-node-01.example.com tasks: - name: Filter logs based on a specific value they contain ansible.builtin.include_role: name: rhel-system-roles.logging vars: logging_inputs: - name: files_input type: basics logging_outputs: - name: files_output0 type: files property: msg property_op: contains property_value: error path: /var/log/errors.log - name: files_output1 type: files property: msg property_op: "!contains" property_value: error path: /var/log/others.log logging_flows: - name: flow0 inputs: [files_input] outputs: [files_output0, files_output1]
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
rsyslogd -N 1 rsyslogd: version 8.1911.0-6.el8, config validation run rsyslogd: End of config validation run. Bye.
logger error
cat /var/log/errors.log Aug 5 13:48:31 hostname root[6778]: error
--- - name: Deploy the logging solution hosts: managed-node-01.example.com tasks: - name: Configure the server to receive remote input ansible.builtin.include_role: name: rhel-system-roles.logging vars: logging_inputs: - name: remote_udp_input type: remote udp_ports: [ 601 ] - name: remote_tcp_input type: remote tcp_ports: [ 601 ] logging_outputs: - name: remote_files_output type: remote_files logging_flows: - name: flow_0 inputs: [remote_udp_input, remote_tcp_input] outputs: [remote_files_output] - name: Deploy the logging solution hosts: managed-node-02.example.com tasks: - name: Configure the server to output the logs to local files in directories named by remote host names ansible.builtin.include_role: name: rhel-system-roles.logging vars: logging_inputs: - name: basic_input type: basics logging_outputs: - name: forward_output0 type: forwards severity: info target: <host1.example.com> udp_port: 601 - name: forward_output1 type: forwards facility: mail target: <host1.example.com> tcp_port: 601 logging_flows: - name: flows0 inputs: [basic_input] outputs: [forward_output0, forward_output1] [basic_input] [forward_output0, forward_output1]
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
rsyslogd -N 1 rsyslogd: version 8.1911.0-6.el8, config validation run (level 1), master config /etc/rsyslog.conf rsyslogd: End of config validation run. Bye.
logger test
cat /var/log/ <host2.example.com> /messages Aug 5 13:48:31 <host2.example.com> root[6778]: test
--- - name: Configure remote logging solution using TLS for secure transfer of logs hosts: managed-node-01.example.com tasks: - name: Deploying files input and forwards output with certs ansible.builtin.include_role: name: rhel-system-roles.logging vars: logging_certificates: - name: logging_cert dns: ['localhost', 'www.example.com'] ca: ipa logging_pki_files: - ca_cert: /local/path/to/ca_cert.pem cert: /local/path/to/logging_cert.pem private_key: /local/path/to/logging_cert.pem logging_inputs: - name: input_name type: files input_log_path: /var/log/containers/*.log logging_outputs: - name: output_name type: forwards target: your_target_host tcp_port: 514 tls: true pki_authmode: x509/name permitted_server: 'server.example.com' logging_flows: - name: flow_name inputs: [input_name] outputs: [output_name]
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Configure remote logging solution using TLS for secure transfer of logs hosts: managed-node-01.example.com tasks: - name: Deploying remote input and remote_files output with certs ansible.builtin.include_role: name: rhel-system-roles.logging vars: logging_certificates: - name: logging_cert dns: ['localhost', 'www.example.com'] ca: ipa logging_pki_files: - ca_cert: /local/path/to/ca_cert.pem cert: /local/path/to/logging_cert.pem private_key: /local/path/to/logging_cert.pem logging_inputs: - name: input_name type: remote tcp_ports: 514 tls: true permitted_clients: ['clients.example.com'] logging_outputs: - name: output_name type: remote_files remote_log_path: /var/log/remote/%FROMHOST%/%PROGRAMNAME:::secpath-replace%.log async_writing: true client_count: 20 io_buffer_size: 8192 logging_flows: - name: flow_name inputs: [input_name] outputs: [output_name]
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Configure client-side of the remote logging solution using RELP hosts: managed-node-01.example.com tasks: - name: Deploy basic input and RELP output ansible.builtin.include_role: name: rhel-system-roles.logging vars: logging_inputs: - name: basic_input type: basics logging_outputs: - name: relp_client type: relp target: logging.server.com port: 20514 tls: true ca_cert: /etc/pki/tls/certs/ca.pem cert: /etc/pki/tls/certs/client-cert.pem private_key: /etc/pki/tls/private/client-key.pem pki_authmode: name permitted_servers: - '*.server.example.com' logging_flows: - name: example_flow inputs: [basic_input] outputs: [relp_client]
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Configure server-side of the remote logging solution using RELP hosts: managed-node-01.example.com tasks: - name: Deploying remote input and remote_files output ansible.builtin.include_role: name: rhel-system-roles.logging vars: logging_inputs: - name: relp_server type: relp port: 20514 tls: true ca_cert: /etc/pki/tls/certs/ca.pem cert: /etc/pki/tls/certs/server-cert.pem private_key: /etc/pki/tls/private/server-key.pem pki_authmode: name permitted_clients: - '*example.client.com' logging_outputs: - name: remote_files_output type: remote_files logging_flows: - name: example_flow inputs: relp_server outputs: remote_files_output
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Monitoring performance metrics hosts: managed-node-01.example.com tasks: - name: Configure Performance Co-Pilot ansible.builtin.include_role: name: rhel-system-roles.metrics vars: metrics_retention_days: 14 metrics_manage_firewall: true metrics_manage_selinux: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'pminfo -f kernel.all.load'
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
metrics_usr: <username> metrics_pwd: <password>
--- - name: Monitoring performance metrics hosts: managed-node-01.example.com tasks: - name: Configure Performance Co-Pilot ansible.builtin.include_role: name: rhel-system-roles.metrics vars: metrics_retention_days: 14 metrics_manage_firewall: true metrics_manage_selinux: true metrics_username: "{{ metrics_usr }}" metrics_password: "{{ metrics_pwd }}"
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
pminfo -fmdt -h pcp://managed-node-01.example.com?username= <user> proc.fd.count Password: <password> proc.fd.count inst [844 or "000844 /var/lib/pcp/pmdas/proc/pmdaproc"] value 5
pminfo -fmdt -h pcp://managed-node-01.example.com proc.fd.count proc.fd.count Error: No permission to perform requested operation
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
grafana_admin_pwd: <password>
--- - name: Monitoring performance metrics hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Set up Grafana to monitor multiple hosts ansible.builtin.include_role: name: rhel-system-roles.metrics vars: metrics_graph_service: true metrics_query_service: true metrics_monitored_hosts: - <pcp_host_1.example.com> - <pcp_host_2.example.com> metrics_manage_firewall: true metrics_manage_selinux: true - name: Set Grafana admin password ansible.builtin.shell: cmd: grafana-cli admin reset-admin-password "{{ grafana_admin_pwd }}"
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
--- - name: Monitoring performance metrics hosts: managed-node-01.example.com tasks: - name: Configure PMIE web hooks ansible.builtin.include_role: name: redhat.rhel_system_roles.metrics vars: metrics_manage_firewall: true metrics_retention_days: 7 metrics_monitored_hosts: - pcp-node-01.example.com - pcp-node-02.example.com metrics_webhook_endpoint: "https://<webserver>:<port>/<endpoint>"
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'pcp summary' Performance Co-Pilot configuration on managed-node-01.example.com: platform: Linux managed-node-node-01.example.com 5.14.0-427.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Feb 23 01:51:18 EST 2024 x86_64 hardware: 8 cpus, 1 disk, 1 node, 1773MB RAM timezone: CEST-2 services: pmcd pmproxy pmcd: Version 6.2.0-1, 12 agents, 6 clients pmda: root pmcd proc pmproxy xfs linux nfsclient mmv kvm jbd2 dm openmetrics pmlogger: primary logger: /var/log/pcp/pmlogger/managed-node-node-01.example.com/20240510.16.25 pcp-node-01.example.com: /var/log/pmlogger/pcp-node-01.example.com/20240510.16.25 pcp-node-02.example.com: /var/log/pmlogger/pcp-node-02.example.com/20240510.16.25 pmie: primary engine: /var/log/pcp/pmie/managed-node-node-01.example.com/pmie.log pcp-node-01.example.com: : /var/log/pcp/pmie/pcp-node-01.example.com/pmie.log pcp-node-02.example.com: : /var/log/pcp/pmie/pcp-node-02.example.com/pmie.log
--- - name: Deploy a Tang server hosts: tang.server.example.com tasks: - name: Install and configure periodic key rotation ansible.builtin.include_role: name: rhel-system-roles.nbde_server vars: nbde_server_rotate_keys: yes nbde_server_manage_firewall: true nbde_server_manage_selinux: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'echo test | clevis encrypt tang '{"url":" <tang.server.example.com> "}' -y | clevis decrypt' test
--- - name: Configure clients for unlocking of encrypted volumes by Tang servers hosts: managed-node-01.example.com tasks: - name: Create NBDE client bindings ansible.builtin.include_role: name: rhel-system-roles.nbde_client vars: nbde_client_bindings: - device: /dev/rhel/root encryption_key_src: /etc/luks/keyfile nbde_client_early_boot: true state: present servers: - http://server1.example.com - http://server2.example.com - device: /dev/rhel/swap encryption_key_src: /etc/luks/keyfile servers: - http://server1.example.com - http://server2.example.com
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'clevis luks list -d /dev/rhel/root' 1: tang '{"url":" <http://server1.example.com/> "}' 2: tang '{"url":" <http://server2.example.com/> "}'
ansible managed-node-01.example.com -m command -a 'lsinitrd | grep clevis-luks' lrwxrwxrwx 1 root root 48 Jan 4 02:56 etc/systemd/system/cryptsetup.target.wants/clevis-luks-askpass.path -> /usr/lib/systemd/system/clevis-luks-askpass.path ...
clients: managed-node-01.example.com: ip_v4: 192.0.2.1 gateway_v4: 192.0.2.254 netmask_v4: 255.255.255.0 interface: enp1s0 managed-node-02.example.com: ip_v4: 192.0.2.2 gateway_v4: 192.0.2.254 netmask_v4: 255.255.255.0 interface: enp1s0
- name: Configure clients for unlocking of encrypted volumes by Tang servers hosts: managed-node-01.example.com,managed-node-02.example.com vars_files: - ~/static-ip-settings-clients.yml tasks: - name: Create NBDE client bindings ansible.builtin.include_role: name: rhel-system-roles.network vars: nbde_client_bindings: - device: /dev/rhel/root encryption_key_src: /etc/luks/keyfile servers: - http://server1.example.com - http://server2.example.com - device: /dev/rhel/swap encryption_key_src: /etc/luks/keyfile servers: - http://server1.example.com - http://server2.example.com - name: Configure a Clevis client with static IP address during early boot ansible.builtin.include_role: name: rhel-system-roles.bootloader vars: bootloader_settings: - kernel: ALL options: - name: ip value: "{{ clients[inventory_hostname]['ip_v4'] }}::{{ clients[inventory_hostname]['gateway_v4'] }}:{{ clients[inventory_hostname]['netmask_v4'] }}::{{ clients[inventory_hostname]['interface'] }}:none"
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
managed-node-01.example.com interface=enp1s0 ip_v4=192.0.2.1/24 ip_v6=2001:db8:1::1/64 gateway_v4=192.0.2.254 gateway_v6=2001:db8:1::fffe managed-node-02.example.com interface=enp1s0 ip_v4=192.0.2.2/24 ip_v6=2001:db8:1::2/64 gateway_v4=192.0.2.254 gateway_v6=2001:db8:1::fffe
--- - name: Configure the network hosts: managed-node-01.example.com,managed-node-02.example.com tasks: - name: Ethernet connection profile with static IP address settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: "{{ interface }}" interface_name: "{{ interface }}" type: ethernet autoconnect: yes ip: address: - "{{ ip_v4 }}" - "{{ ip_v6 }}" gateway4: "{{ gateway_v4 }}" gateway6: "{{ gateway_v6 }}" dns: - 192.0.2.200 - 2001:db8:1::ffbb dns_search: - example.com state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.setup "ansible_default_ipv4": { "address": "192.0.2.1", "alias": "enp1s0", "broadcast": "192.0.2.255", "gateway": "192.0.2.254", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "netmask": "255.255.255.0", "network": "192.0.2.0", "prefix": "24", "type": "ether" }, "ansible_default_ipv6": { "address": "2001:db8:1::1", "gateway": "2001:db8:1::fffe", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "prefix": "64", "scope": "global", "type": "ether" }, "ansible_dns": { "nameservers": [ "192.0.2.1", "2001:db8:1::ffbb" ], "search": [ "example.com" ] },
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with static IP address settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: example match: path: - pci-0000:00:0[1-3].0 - &!pci-0000:00:02.0 type: ethernet autoconnect: yes ip: address: - 192.0.2.1/24 - 2001:db8:1::1/64 gateway4: 192.0.2.254 gateway6: 2001:db8:1::fffe dns: - 192.0.2.200 - 2001:db8:1::ffbb dns_search: - example.com state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.setup "ansible_default_ipv4": { "address": "192.0.2.1", "alias": "enp1s0", "broadcast": "192.0.2.255", "gateway": "192.0.2.254", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "netmask": "255.255.255.0", "network": "192.0.2.0", "prefix": "24", "type": "ether" }, "ansible_default_ipv6": { "address": "2001:db8:1::1", "gateway": "2001:db8:1::fffe", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "prefix": "64", "scope": "global", "type": "ether" }, "ansible_dns": { "nameservers": [ "192.0.2.1", "2001:db8:1::ffbb" ], "search": [ "example.com" ] },
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with dynamic IP address settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: enp1s0 interface_name: enp1s0 type: ethernet autoconnect: yes ip: dhcp4: yes auto6: yes state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.setup "ansible_default_ipv4": { "address": "192.0.2.1", "alias": "enp1s0", "broadcast": "192.0.2.255", "gateway": "192.0.2.254", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "netmask": "255.255.255.0", "network": "192.0.2.0", "prefix": "24", "type": "ether" }, "ansible_default_ipv6": { "address": "2001:db8:1::1", "gateway": "2001:db8:1::fffe", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "prefix": "64", "scope": "global", "type": "ether" }, "ansible_dns": { "nameservers": [ "192.0.2.1", "2001:db8:1::ffbb" ], "search": [ "example.com" ] },
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with dynamic IP address settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: example match: path: - pci-0000:00:0[1-3].0 - &!pci-0000:00:02.0 type: ethernet autoconnect: yes ip: dhcp4: yes auto6: yes state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.setup "ansible_default_ipv4": { "address": "192.0.2.1", "alias": "enp1s0", "broadcast": "192.0.2.255", "gateway": "192.0.2.254", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "netmask": "255.255.255.0", "network": "192.0.2.0", "prefix": "24", "type": "ether" }, "ansible_default_ipv6": { "address": "2001:db8:1::1", "gateway": "2001:db8:1::fffe", "interface": "enp1s0", "macaddress": "52:54:00:17:b8:b6", "mtu": 1500, "prefix": "64", "scope": "global", "type": "ether" }, "ansible_dns": { "nameservers": [ "192.0.2.1", "2001:db8:1::ffbb" ], "search": [ "example.com" ] },
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
pwd: <password>
--- - name: Configure an Ethernet connection with 802.1X authentication hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Copy client key for 802.1X authentication ansible.builtin.copy: src: "/srv/data/client.key" dest: "/etc/pki/tls/private/client.key" mode: 0600 - name: Copy client certificate for 802.1X authentication ansible.builtin.copy: src: "/srv/data/client.crt" dest: "/etc/pki/tls/certs/client.crt" - name: Copy CA certificate for 802.1X authentication ansible.builtin.copy: src: "/srv/data/ca.crt" dest: "/etc/pki/ca-trust/source/anchors/ca.crt" - name: Ethernet connection profile with static IP address settings and 802.1X ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: enp1s0 type: ethernet autoconnect: yes ip: address: - 192.0.2.1/24 - 2001:db8:1::1/64 gateway4: 192.0.2.254 gateway6: 2001:db8:1::fffe dns: - 192.0.2.200 - 2001:db8:1::ffbb dns_search: - example.com ieee802_1x: identity: <user_name> eap: tls private_key: "/etc/pki/tls/private/client.key" private_key_password: "{{ pwd }}" client_cert: "/etc/pki/tls/certs/client.crt" ca_cert: "/etc/pki/ca-trust/source/anchors/ca.crt" domain_suffix_match: example.com state: up
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
pwd: <password>
--- - name: Configure a wifi connection with 802.1X authentication hosts: managed-node-01.example.com tasks: - name: Copy client key for 802.1X authentication ansible.builtin.copy: src: "/srv/data/client.key" dest: "/etc/pki/tls/private/client.key" mode: 0400 - name: Copy client certificate for 802.1X authentication ansible.builtin.copy: src: "/srv/data/client.crt" dest: "/etc/pki/tls/certs/client.crt" - name: Copy CA certificate for 802.1X authentication ansible.builtin.copy: src: "/srv/data/ca.crt" dest: "/etc/pki/ca-trust/source/anchors/ca.crt" - name: Wifi connection profile with dynamic IP address settings and 802.1X ansible.builtin.import_role: name: rhel-system-roles.network vars: network_connections: - name: Wifi connection profile with dynamic IP address settings and 802.1X interface_name: wlp1s0 state: up type: wireless autoconnect: yes ip: dhcp4: true auto6: true wireless: ssid: "Example-wifi" key_mgmt: "wpa-eap" ieee802_1x: identity: <user_name> eap: tls private_key: "/etc/pki/tls/client.key" private_key_password: "{{ pwd }}" private_key_password_flags: none client_cert: "/etc/pki/tls/client.pem" ca_cert: "/etc/pki/tls/cacert.pem" domain_suffix_match: "example.com"
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Bond connection profile with two Ethernet ports ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: # Bond profile - name: bond0 type: bond interface_name: bond0 ip: dhcp4: yes auto6: yes bond: mode: active-backup state: up # Port profile for the 1st Ethernet device - name: bond0-port1 interface_name: enp7s0 type: ethernet controller: bond0 state: up # Port profile for the 2nd Ethernet device - name: bond0-port2 interface_name: enp8s0 type: ethernet controller: bond0 state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: VLAN connection profile with Ethernet port ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: # Ethernet profile - name: enp1s0 type: ethernet interface_name: enp1s0 autoconnect: yes state: up ip: dhcp4: no auto6: no # VLAN profile - name: enp1s0.10 type: vlan vlan: id: 10 ip: dhcp4: yes auto6: yes parent: enp1s0 state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ip -d addr show enp1s0.10' managed-node-01.example.com | CHANGED | rc=0 >> 4: vlan10@enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 52:54:00:72:2f:6e brd ff:ff:ff:ff:ff:ff promiscuity 0 vlan protocol 802.1Q id 10 <REORDER_HDR> numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Bridge connection profile with two Ethernet ports ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: # Bridge profile - name: bridge0 type: bridge interface_name: bridge0 ip: dhcp4: yes auto6: yes state: up # Port profile for the 1st Ethernet device - name: bridge0-port1 interface_name: enp7s0 type: ethernet controller: bridge0 port_type: bridge state: up # Port profile for the 2nd Ethernet device - name: bridge0-port2 interface_name: enp8s0 type: ethernet controller: bridge0 port_type: bridge state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ip link show master bridge0' managed-node-01.example.com | CHANGED | rc=0 >> 3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master bridge0 state UP mode DEFAULT group default qlen 1000 link/ether 52:54:00:62:61:0e brd ff:ff:ff:ff:ff:ff 4: enp8s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master bridge0 state UP mode DEFAULT group default qlen 1000 link/ether 52:54:00:9e:f1:ce brd ff:ff:ff:ff:ff:ff
ansible managed-node-01.example.com -m command -a 'bridge link show' managed-node-01.example.com | CHANGED | rc=0 >> 3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master bridge0 state forwarding priority 32 cost 100 4: enp8s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master bridge0 state listening priority 32 cost 100
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with static IP address settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: enp1s0 type: ethernet autoconnect: yes ip: address: - 198.51.100.20/24 - 2001:db8:1::1/64 gateway4: 198.51.100.254 gateway6: 2001:db8:1::fffe dns: - 198.51.100.200 - 2001:db8:1::ffbb dns_search: - example.com state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.setup "ansible_default_ipv4": { "gateway": "198.51.100.254", "interface": "enp1s0", }, "ansible_default_ipv6": { "gateway": "2001:db8:1::fffe", "interface": "enp1s0", }
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with static IP address settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: enp7s0 type: ethernet autoconnect: yes ip: address: - 192.0.2.1/24 - 2001:db8:1::1/64 gateway4: 192.0.2.254 gateway6: 2001:db8:1::fffe dns: - 192.0.2.200 - 2001:db8:1::ffbb dns_search: - example.com route: - network: 198.51.100.0 prefix: 24 gateway: 192.0.2.10 - network: 2001:db8:2:: prefix: 64 gateway: 2001:db8:1::10 state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ip -4 route' managed-node-01.example.com | CHANGED | rc=0 >> 198.51.100.0/24 via 192.0.2.10 dev enp7s0
ansible managed-node-01.example.com -m command -a 'ip -6 route' managed-node-01.example.com | CHANGED | rc=0 >> 2001:db8:2::/64 via 2001:db8:1::10 dev enp7s0 metric 1024 pref medium
--- - name: Configuring policy-based routing hosts: managed-node-01.example.com tasks: - name: Routing traffic from a specific subnet to a different default gateway ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: Provider-A interface_name: enp7s0 type: ethernet autoconnect: True ip: address: - 198.51.100.1/30 gateway4: 198.51.100.2 dns: - 198.51.100.200 state: up zone: external - name: Provider-B interface_name: enp1s0 type: ethernet autoconnect: True ip: address: - 192.0.2.1/30 route: - network: 0.0.0.0 prefix: 0 gateway: 192.0.2.2 table: 5000 state: up zone: external - name: Internal-Workstations interface_name: enp8s0 type: ethernet autoconnect: True ip: address: - 10.0.0.1/24 route: - network: 10.0.0.0 prefix: 24 table: 5000 routing_rule: - priority: 5 from: 10.0.0.0/24 table: 5000 state: up zone: trusted - name: Servers interface_name: enp9s0 type: ethernet autoconnect: True ip: address: - 203.0.113.1/24 state: up zone: trusted
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
dnf install traceroute
traceroute redhat.com traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets 1 10.0.0.1 (10.0.0.1) 0.337 ms 0.260 ms 0.223 ms 2 192.0.2.1 (192.0.2.1) 0.884 ms 1.066 ms 1.248 ms
dnf install traceroute
traceroute redhat.com traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets 1 203.0.113.1 (203.0.113.1) 2.179 ms 2.073 ms 1.944 ms 2 198.51.100.2 (198.51.100.2) 1.868 ms 1.798 ms 1.549 ms
ip rule list 0: from all lookup local 5 : from 10.0.0.0/24 lookup 5000 32766: from all lookup main 32767: from all lookup default
ip route list table 5000 0.0.0.0/0 via 192.0.2.2 dev enp1s0 proto static metric 100 10.0.0.0/24 dev enp8s0 proto static scope link src 192.0.2.1 metric 102
firewall-cmd --get-active-zones external interfaces: enp1s0 enp7s0 trusted interfaces: enp8s0 enp9s0
firewall-cmd --info-zone=external external (active) target: default icmp-block-inversion: no interfaces: enp1s0 enp7s0 sources: services: ssh ports: protocols: masquerade: yes
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with dynamic IP address settings and offload features ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: enp1s0 type: ethernet autoconnect: yes ip: dhcp4: yes auto6: yes ethtool: features: gro: no gso: yes tx_sctp_segmentation: no state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m ansible.builtin.setup "ansible_enp1s0": { "active": true, "device": "enp1s0", "features": { "rx_gro_hw": "off, "tx_gso_list": "on, "tx_sctp_segmentation": "off", }
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with dynamic IP address settings and coalesce settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: enp1s0 type: ethernet autoconnect: yes ip: dhcp4: yes auto6: yes ethtool: coalesce: rx_frames: 128 tx_frames: 128 state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ethtool -c enp1s0' managed-node-01.example.com | CHANGED | rc=0 >> rx-frames: 128 tx-frames: 128
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: Ethernet connection profile with dynamic IP address setting and increased ring buffer sizes ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: enp1s0 type: ethernet autoconnect: yes ip: dhcp4: yes auto6: yes ethtool: ring: rx: 4096 tx: 4096 state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ethtool -g enp1s0' managed-node-01.example.com | CHANGED | rc=0 >> Current hardware settings: RX: 4096 RX Mini: 0 RX Jumbo: 0 TX: 4096
--- - name: Configure the network hosts: managed-node-01.example.com tasks: - name: IPoIB connection profile with static IP address settings ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: # InfiniBand connection mlx4_ib0 - name: mlx4_ib0 interface_name: mlx4_ib0 type: infiniband # IPoIB device mlx4_ib0.8002 on top of mlx4_ib0 - name: mlx4_ib0.8002 type: infiniband autoconnect: yes infiniband: p_key: 0x8002 transport_mode: datagram parent: mlx4_ib0 ip: address: - 192.0.2.1/24 - 2001:db8:1::1/64 state: up
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ip address show mlx4_ib0.8002' managed-node-01.example.com | CHANGED | rc=0 >> inet 192.0.2.1/24 brd 192.0.2.255 scope global noprefixroute ib0.8002 valid_lft forever preferred_lft forever inet6 2001:db8:1::1/64 scope link tentative noprefixroute valid_lft forever preferred_lft forever
ansible managed-node-01.example.com -m command -a 'cat /sys/class/net/mlx4_ib0.8002/pkey' managed-node-01.example.com | CHANGED | rc=0 >> 0x8002
ansible managed-node-01.example.com -m command -a 'cat /sys/class/net/mlx4_ib0.8002/mode' managed-node-01.example.com | CHANGED | rc=0 >> datagram
vars: network_state: interfaces: - name: enp7s0 type: ethernet state: up ipv4: enabled: true auto-dns: true auto-gateway: true auto-routes: true dhcp: true ipv6: enabled: true auto-dns: true auto-gateway: true auto-routes: true autoconf: true dhcp: true
vars: network_connections: - name: enp7s0 interface_name: enp7s0 type: ethernet autoconnect: yes ip: dhcp4: yes auto6: yes state: up
vars: network_state: interfaces: - name: enp7s0 type: ethernet state: down
vars: network_connections: - name: enp7s0 interface_name: enp7s0 type: ethernet autoconnect: yes ip: dhcp4: yes auto6: yes state: down
- name: Configure Podman hosts: managed-node-01.example.com tasks: - name: Create a web application and a database ansible.builtin.include_role: name: rhel-system-roles.podman vars: podman_create_host_directories: true podman_firewall: - port: 8080-8081/tcp state: enabled - port: 12340/tcp state: enabled podman_selinux_ports: - ports: 8080-8081 setype: http_port_t podman_kube_specs: - state: started run_as_user: dbuser run_as_group: dbgroup kube_file_content: apiVersion: v1 kind: Pod metadata: name: db spec: containers: - name: db image: quay.io/linux-system-roles/mysql:5.6 ports: - containerPort: 1234 hostPort: 12340 volumeMounts: - mountPath: /var/lib/db:Z name: db volumes: - name: db hostPath: path: /var/lib/db - state: started run_as_user: webapp run_as_group: webapp kube_file_src: /path/to/webapp.yml
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
- name: Configure Podman hosts: managed-node-01.example.com tasks: - name: Start Apache server on port 8080 ansible.builtin.include_role: name: rhel-system-roles.podman vars: podman_firewall: - port: 8080/tcp state: enabled podman_kube_specs: - state: started kube_file_content: apiVersion: v1 kind: Pod metadata: name: ubi8-httpd spec: containers: - name: ubi8-httpd image: registry.access.redhat.com/ubi8/httpd-24 ports: - containerPort: 8080 hostPort: 8080 volumeMounts: - mountPath: /var/www/html:Z name: ubi8-html volumes: - name: ubi8-html persistentVolumeClaim: claimName: ubi8-html-volume
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
cat ~/certificate.pem -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- cat ~/key.pem -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY-----
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
root_password: <root_password> certificate: |- -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- key: |- -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY-----
- name: Deploy a wordpress CMS with MySQL database hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Create and run the container ansible.builtin.include_role: name: rhel-system-roles.podman vars: podman_create_host_directories: true podman_activate_systemd_unit: false podman_quadlet_specs: - name: quadlet-demo type: network file_content: | [Network] Subnet=192.168.30.0/24 Gateway=192.168.30.1 Label=app=wordpress - file_src: quadlet-demo-mysql.volume - template_src: quadlet-demo-mysql.container.j2 - file_src: envoy-proxy-configmap.yml - file_src: quadlet-demo.yml - file_src: quadlet-demo.kube activate_systemd_unit: true podman_firewall: - port: 8000/tcp state: enabled - port: 9000/tcp state: enabled podman_secrets: - name: mysql-root-password-container state: present skip_existing: true data: "{{ root_password }}" - name: mysql-root-password-kube state: present skip_existing: true data: | apiVersion: v1 data: password: "{{ root_password | b64encode }}" kind: Secret metadata: name: mysql-root-password-kube - name: envoy-certificates state: present skip_existing: true data: | apiVersion: v1 data: certificate.key: {{ key | b64encode }} certificate.pem: {{ certificate | b64encode }} kind: Secret metadata: name: envoy-certificates
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
--- - name: Manage Postfix hosts: managed-node-01.example.com tasks: - name: Install postfix ansible.builtin.package: name: postfix state: present - name: Configure null client for only sending outgoing emails ansible.builtin.include_role: name: rhel-system-roles.postfix vars: postfix_conf: myhostname: server.example.com myorigin: "USDmydomain" relayhost: smtp.example.com inet_interfaces: loopback-only mydestination: "" relay_domains: "{{ lookup('ansible.builtin.pipe', 'postconf -h default_database_type') }}:/etc/postfix/relay_domains" postfix_files: - name: relay_domains postmap: true content: | example.com OK example.net OK
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
pwd: <password>
--- - name: Installing and configuring PostgreSQL hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Create directory for TLS certificate and key ansible.builtin.file: path: /etc/postgresql/ state: directory mode: 755 - name: Copy CA certificate ansible.builtin.copy: src: "~/{{ inventory_hostname }}.crt" dest: "/etc/postgresql/server.crt" - name: Copy private key ansible.builtin.copy: src: "~/{{ inventory_hostname }}.key" dest: "/etc/postgresql/server.key" mode: 0600 - name: PostgreSQL with an existing private key and certificate ansible.builtin.include_role: name: rhel-system-roles.postgresql vars: postgresql_version: "16" postgresql_password: "{{ pwd }}" postgresql_ssl_enable: true postgresql_cert_name: "/etc/postgresql/server" postgresql_server_conf: listen_addresses: "'*'" password_encryption: scram-sha-256 postgresql_pg_hba_conf: - type: local database: all user: all auth_method: scram-sha-256 - type: hostssl database: all user: all address: '127.0.0.1/32' auth_method: scram-sha-256 - type: hostssl database: all user: all address: '::1/128' auth_method: scram-sha-256 - type: hostssl database: all user: all address: '192.0.2.0/24' auth_method: scram-sha-256 - name: Open the PostgresQL port in firewalld ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - service: postgresql state: enabled
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
psql "postgresql://postgres@managed-node-01.example.com:5432" -c '\conninfo' Password for user postgres: You are connected to database "postgres" as user "postgres" on host "192.0.2.1" at port "5432". SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
pwd: <password>
--- - name: Installing and configuring PostgreSQL hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: PostgreSQL with certificates issued by IdM ansible.builtin.include_role: name: rhel-system-roles.postgresql vars: postgresql_version: "16" postgresql_password: "{{ pwd }}" postgresql_ssl_enable: true postgresql_certificates: - name: postgresql_cert dns: "{{ inventory_hostname }}" ca: ipa principal: "postgresql/{{ inventory_hostname }}@EXAMPLE.COM" postgresql_server_conf: listen_addresses: "'*'" password_encryption: scram-sha-256 postgresql_pg_hba_conf: - type: local database: all user: all auth_method: scram-sha-256 - type: hostssl database: all user: all address: '127.0.0.1/32' auth_method: scram-sha-256 - type: hostssl database: all user: all address: '::1/128' auth_method: scram-sha-256 - type: hostssl database: all user: all address: '192.0.2.0/24' auth_method: scram-sha-256 - name: Open the PostgresQL port in firewalld ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - service: postgresql state: enabled
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
psql "postgresql://postgres@managed-node-01.example.com:5432" -c '\conninfo' Password for user postgres: You are connected to database "postgres" as user "postgres" on host "192.0.2.1" at port "5432". SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
ansible-vault create vault.yml New Vault password: <password> Confirm New Vault password: <vault_password>
activationKey: <activation_key> organizationID: <organizationID> username: <username> password: <password>
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Registering system using activation key and organization ID ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_auth: activation_keys: keys: - "{{ activationKey }}" rhc_organization: "{{ organizationID }}"
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Registering system with username and password ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_auth: login: username: "{{ username }}" password: "{{ password }}"
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <password> Confirm New Vault password: <vault_password>
activationKey: <activation_key> organizationID: <organizationID>
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Register to the custom registration server and CDN ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_auth: activation_keys: keys: - "{{ activationKey }}" rhc_organization: "{{ organizationID }}" rhc_server: hostname: example.com port: 443 prefix: /rhsm rhc_baseurl: http://example.com/pulp/content
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com tasks: - name: Disable Insights connection ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_insights: state: absent
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com tasks: - name: Enable repository ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_repositories: - name: "RepositoryName" state: enabled
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com tasks: - name: Lock the system to a particular release ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_release: "8.6"
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible-vault create vault.yml New Vault password: <password> Confirm New Vault password: <vault_password>
username: <username> password: <password> proxy_username: <proxyusernme> proxy_password: <proxypassword>
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Register to the Red Hat Customer Portal by using proxy ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_auth: login: username: "{{ username }}" password: "{{ password }}" rhc_proxy: hostname: proxy.example.com port: 3128 username: "{{ proxy_username }}" password: "{{ proxy_password }}"
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible-vault create vault.yml New Vault password: <password> Confirm New Vault password: <vault_password>
username: <username> password: <password>
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Enable Red Hat Insights autoupdates ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_auth: login: username: "{{ username }}" password: "{{ password }}" rhc_insights: autoupdate: true state: present
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com tasks: - name: Disable remediation ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_insights: remediation: absent state: present
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible-vault create vault.yml New Vault password: <password> Confirm New Vault password: <vault_password>
username: <username> password: <password>
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Creating tags ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_auth: login: username: "{{ username }}" password: "{{ password }}" rhc_insights: tags: group: group-name-value location: location-name-value description: - RHEL8 - SAP sample_key: value state: present
ansible-playbook --syntax-check --ask-vault-pass ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
--- - name: Managing systems with the rhc RHEL system role hosts: managed-node-01.example.com tasks: - name: Unregister the system ansible.builtin.include_role: name: rhel-system-roles.rhc vars: rhc_state: absent
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
cp /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml <my-selinux-playbook.yml> vi <my-selinux-playbook.yml>
selinux_modules: - { path: "selinux-local-1.pp", priority: "400" }
ansible-playbook <my-selinux-playbook.yml> --syntax-check
ansible-playbook <my-selinux-playbook.yml>
- name: Allow Apache to listen on tcp port <port_number> community.general.seport: ports: <port_number> proto: tcp setype: http_port_t state: present
--- - name: Modify SELinux port mapping example hosts: all vars: # Map tcp port <port_number> to the 'http_port_t' SELinux port type selinux_ports: - ports: <port_number> proto: tcp setype: http_port_t state: present tasks: - name: Include selinux role ansible.builtin.include_role: name: rhel-system-roles.selinux
semanage port --list | grep http_port_t http_port_t tcp <port_number> , 80, 81, 443, 488, 8008, 8009, 8443, 9000
sshd_ListenAddress: - 0.0.0.0 - '::'
ListenAddress 0.0.0.0 ListenAddress ::
--- - name: SSH server configuration hosts: managed-node-01.example.com tasks: - name: Configure sshd to prevent root and password login except from particular subnet ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd: PermitRootLogin: no PasswordAuthentication: no Match: - Condition: "Address 192.0.2.0/24" PermitRootLogin: yes PasswordAuthentication: yes
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ssh <username> @ <ssh_server>
cat /etc/ssh/sshd_config.d/00-ansible_system_role.conf # Ansible managed # PasswordAuthentication no PermitRootLogin no Match Address 192.0.2.0/24 PasswordAuthentication yes PermitRootLogin yes
hostname -I 192.0.2.1
ssh root@ <ssh_server>
--- - name: Non-exclusive sshd configuration hosts: managed-node-01.example.com tasks: - name: Configure SSHD to accept environment variables ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd_config_namespace: <my-application> sshd: # Environment variables to accept AcceptEnv: LANG LS_COLORS EDITOR
- name: Non-exclusive sshd configuration hosts: managed-node-01.example.com tasks: - name: Configure sshd to accept environment variables ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd_config_file: /etc/ssh/sshd_config.d/ <42-my-application> .conf sshd: # Environment variables to accept AcceptEnv: LANG LS_COLORS EDITOR
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
cat /etc/ssh/sshd_config BEGIN sshd system role managed block: namespace <my-application> Match all AcceptEnv LANG LS_COLORS EDITOR END sshd system role managed block: namespace <my-application>
cat /etc/ssh/sshd_config.d/42-my-application.conf Ansible managed # AcceptEnv LANG LS_COLORS EDITOR
- name: Deploy SSH configuration for OpenSSH server hosts: managed-node-01.example.com tasks: - name: Overriding the system-wide cryptographic policy ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd_sysconfig: true sshd_sysconfig_override_crypto_policy: true sshd_KexAlgorithms: ecdh-sha2-nistp521 sshd_Ciphers: aes256-ctr sshd_MACs: hmac-sha2-512-etm@openssh.com sshd_HostKeyAlgorithms: rsa-sha2-512,rsa-sha2-256
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ssh -vvv <ssh_server> debug2: peer server KEXINIT proposal debug2: KEX algorithms: ecdh-sha2-nistp521 debug2: host key algorithms: rsa-sha2-512,rsa-sha2-256 debug2: ciphers ctos: aes256-ctr debug2: ciphers stoc: aes256-ctr debug2: MACs ctos: hmac-sha2-512-etm@openssh.com debug2: MACs stoc: hmac-sha2-512-etm@openssh.com
LocalForward: - 22 localhost:2222 - 403 localhost:4003
LocalForward 22 localhost:2222 LocalForward 403 localhost:4003
--- - name: SSH client configuration hosts: managed-node-01.example.com tasks: - name: Configure ssh clients ansible.builtin.include_role: name: rhel-system-roles.ssh vars: ssh_user: root ssh: Compression: true GSSAPIAuthentication: no ControlMaster: auto ControlPath: ~/.ssh/.cm%C Host: - Condition: example Hostname: server.example.com User: user1 ssh_ForwardX11: no
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
cat ~/root/.ssh/config Ansible managed Compression yes ControlMaster auto ControlPath ~/.ssh/.cm%C ForwardX11 no GSSAPIAuthentication no Host example Hostname example.com User user1
--- - hosts: managed-node-01.example.com roles: - rhel-system-roles.storage vars: storage_volumes: - name: barefs type: disk disks: - sdb fs_type: xfs
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - hosts: managed-node-01.example.com roles: - rhel-system-roles.storage vars: storage_volumes: - name: barefs type: disk disks: - sdb fs_type: xfs mount_point: /mnt/data mount_user: somebody mount_group: somegroup mount_mode: 0755
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Manage local storage hosts: managed-node-01.example.com tasks: - name: Create logical volume ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_pools: - name: myvg disks: - sda - sdb - sdc volumes: - name: mylv size: 2G fs_type: ext4 mount_point: /mnt/data
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'lvs myvg'
--- - name: Manage local storage hosts: managed-node-01.example.com tasks: - name: Enable online block discard ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_volumes: - name: barefs type: disk disks: - sdb fs_type: xfs mount_point: /mnt/data mount_options: discard
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'findmnt /mnt/data'
--- - hosts: managed-node-01.example.com roles: - rhel-system-roles.storage vars: storage_volumes: - name: barefs type: disk disks: - sdb fs_type: ext4 fs_label: label-name mount_point: /mnt/data
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - hosts: all roles: - rhel-system-roles.storage vars: storage_volumes: - name: barefs type: disk disks: - sdb fs_type: ext3 fs_label: label-name mount_point: /mnt/data mount_user: somebody mount_group: somegroup mount_mode: 0755
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Create a disk device with swap hosts: managed-node-01.example.com roles: - rhel-system-roles.storage vars: storage_volumes: - name: swap_fs type: disk disks: - /dev/sdb size: 15 GiB fs_type: swap
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Manage local storage hosts: managed-node-01.example.com tasks: - name: Create a RAID on sdd, sde, sdf, and sdg ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_safe_mode: false storage_volumes: - name: data type: raid disks: [sdd, sde, sdf, sdg] raid_level: raid0 raid_chunk_size: 32 KiB mount_point: /mnt/data state: present
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'mdadm --detail /dev/md/data'
--- - name: Manage local storage hosts: managed-node-01.example.com tasks: - name: Configure LVM pool with RAID ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_safe_mode: false storage_pools: - name: my_pool type: lvm disks: [sdh, sdi] raid_level: raid1 volumes: - name: my_volume size: "1 GiB" mount_point: "/mnt/app/shared" fs_type: xfs state: present
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'lsblk'
--- - name: Manage local storage hosts: managed-node-01.example.com tasks: - name: Configure stripe size for RAID LVM volumes ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_safe_mode: false storage_pools: - name: my_pool type: lvm disks: [sdh, sdi] volumes: - name: my_volume size: "1 GiB" mount_point: "/mnt/app/shared" fs_type: xfs raid_level: raid0 raid_stripe_size: "256 KiB" state: present
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'lvs -o+stripesize /dev/my_pool/my_volume'
--- - name: Manage local storage hosts: managed-node-01.example.com tasks: - name: Create LVM-VDO volume under volume group 'myvg' ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_pools: - name: myvg disks: - /dev/sdb volumes: - name: mylv1 compression: true deduplication: true vdo_pool_size: 10 GiB size: 30 GiB mount_point: /mnt/app/shared
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'lvs -o+vdo_compression,vdo_compression_state,vdo_deduplication,vdo_index_state' LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert VDOCompression VDOCompressionState VDODeduplication VDOIndexState mylv1 myvg vwi-a-v--- 3.00t vpool0 enabled online enabled online
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
luks_password: <password>
--- - name: Manage local storage hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Create and configure a volume encrypted with LUKS ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_volumes: - name: barefs type: disk disks: - sdb fs_type: xfs fs_label: <label> mount_point: /mnt/data encryption: true encryption_password: "{{ luks_password }}"
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'cryptsetup luksUUID /dev/sdb' 4e4e7970-1822-470e-b55a-e91efe5d0f5c
ansible managed-node-01.example.com -m command -a 'cryptsetup status luks-4e4e7970-1822-470e-b55a-e91efe5d0f5c' /dev/mapper/luks-4e4e7970-1822-470e-b55a-e91efe5d0f5c is active and is in use. type: LUKS2 cipher: aes-xts-plain64 keysize: 512 bits key location: keyring device: /dev/sdb
ansible managed-node-01.example.com -m command -a 'cryptsetup luksDump /dev/sdb' LUKS header information Version: 2 Epoch: 3 Metadata area: 16384 [bytes] Keyslots area: 16744448 [bytes] UUID: 4e4e7970-1822-470e-b55a-e91efe5d0f5c Label: (no label) Subsystem: (no subsystem) Flags: (no flags) Data segments: 0: crypt offset: 16777216 [bytes] length: (whole device) cipher: aes-xts-plain64 sector: 512 [bytes]
--- - name: Manage local storage hosts: managed-node-01.example.com become: true tasks: - name: Create shared LVM device ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_pools: - name: vg1 disks: /dev/vdb type: lvm shared: true state: present volumes: - name: lv1 size: 4g mount_point: /opt/test1 storage_safe_mode: false storage_use_partitions: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
--- - name: Manage local storage hosts: managed-node-01.example.com tasks: - name: Resize LVM PV size ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_pools: - name: myvg disks: ["sdf"] type: lvm grow_to_fill: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'pvs' PV VG Fmt Attr PSize PFree /dev/sdf1 myvg lvm2 a-- 1,99g 1,99g
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
luks_password: <password>
--- - name: Manage local storage hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: Create a new encrypted Stratis pool with Clevis and Tang ansible.builtin.include_role: name: rhel-system-roles.storage vars: storage_pools: - name: mypool disks: - sdd - sde type: stratis encryption: true encryption_password: "{{ luks_password }}" encryption_clevis_pin: tang encryption_tang_url: tang-server.example.com:7500
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'sudo stratis report' "clevis_config": { "thp": "j-G4ddvdbVfxpnUbgxlpbe3KutSKmcHttILAtAkMTNA", "url": "tang-server.example.com:7500" }, "clevis_pin": "tang", "in_use": true, "key_description": "blivet-mypool",
--- - name: "Configure sudo" hosts: managed-node-01.example.com tasks: - name: "Apply custom /etc/sudoers configuration" ansible.builtin.include_role: name: rhel-system-roles.sudo vars: sudo_sudoers_files: - path: "/etc/sudoers" user_specifications: - users: - <user_name> hosts: - <host_name> commands: - <path_to_command_binary>
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
cat /etc/sudoers | tail -n1 <user_name> <host_name> = <path_to_command_binary>
--- - name: Managing systemd services hosts: managed-node-01.example.com tasks: - name: Perform action on systemd units ansible.builtin.include_role: name: rhel-system-roles.systemd vars: systemd_started_units: - <systemd_unit_1> .service systemd_stopped_units: - <systemd_unit_2> .service systemd_restarted_units: - <systemd_unit_3> .service systemd_reloaded_units: - <systemd_unit_4> .service systemd_enabled_units: - <systemd_unit_5> .service systemd_disabled_units: - <systemd_unit_6> .service systemd_masked_units: - <systemd_unit_7> .service systemd_unmasked_units: - <systemd_unit_8> .service
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
{{ ansible_managed | comment }} [Unit] After= After=network.target sshd-keygen.target network-online.target
--- - name: Managing systemd services hosts: managed-node-01.example.com tasks: - name: Deploy an sshd.service systemd drop-in file ansible.builtin.include_role: name: rhel-system-roles.systemd vars: systemd_dropins: - sshd.service.conf.j2
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ls /etc/systemd/system/sshd.service.d/' 99-override.conf
{{ ansible_managed | comment }} [Unit] Description=Example systemd service unit file [Service] ExecStart=/bin/true
--- - name: Managing systemd services hosts: managed-node-01.example.com tasks: - name: Deploy, enable, and start a custom systemd service ansible.builtin.include_role: name: rhel-system-roles.systemd vars: systemd_unit_file_templates: - example.service.j2 systemd_enabled_units: - example.service systemd_started_units: - example.service
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'systemctl status example.service' ● example.service - A service for demonstrating purposes Loaded: loaded (/etc/systemd/system/example.service; enabled ; vendor preset: disabled) Active: active (running) since Thu 2024-07-04 15:59:18 CEST; 10min ago
--- - name: Managing time synchronization hosts: managed-node-01.example.com tasks: - name: Configuring NTP with an internal server (preferred) and a public server pool as fallback ansible.builtin.include_role: name: rhel-system-roles.timesync vars: timesync_ntp_servers: - hostname: time.example.com trusted: yes prefer: yes iburst: yes - hostname: 0.rhel.pool.ntp.org pool: yes iburst: yes
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'chronyc sources' MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* time.example.com 1 10 377 210 +159us[ +55us] +/- 12ms ^? ntp.example.org 2 9 377 409 +1120us[+1021us] +/- 42ms ^? time.us.example.net 2 9 377 992 -329us[ -386us] +/- 15ms
ansible managed-node-01.example.com -m command -a 'ntpq -p' remote refid st t when poll reach delay offset jitter ============================================================================== *time.example.com .PTB. 1 u 2 64 77 23.585 967.902 0.684 - ntp.example.or 192.0.2.17 2 u - 64 77 27.090 966.755 0.468 +time.us.example 198.51.100.19 2 u 65 64 37 18.497 968.463 1.588
--- - name: Managing time synchronization hosts: managed-node-01.example.com tasks: - name: Configuring NTP with NTS-enabled servers ansible.builtin.include_role: name: rhel-system-roles.timesync vars: timesync_ntp_servers: - hostname: ptbtime1.ptb.de nts: yes iburst: yes
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'chronyc sources' MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* ptbtime1.ptb.de 1 6 17 55 -13us[ -54us] +/- 12ms ^- ptbtime2.ptb.de 1 6 17 56 -257us[ -297us] +/- 12ms
ansible managed-node-01.example.com -m command -a 'chronyc -N authdata' Name/IP address Mode KeyID Type KLen Last Atmp NAK Cook CLen ========================================================================= ptbtime1.ptb.de NTS 1 15 256 229 0 0 8 100 ptbtime2.ptb.de NTS 1 15 256 230 0 0 8 100
ansible managed-node-01.example.com -m command -a 'ntpq -p' remote refid st t when poll reach delay offset jitter ============================================================================== *ptbtime1.ptb.de .PTB. 1 8 2 64 77 23.585 967.902 0.684 -ptbtime2.ptb.de .PTB. 1 8 30 64 78 24.653 993.937 0.765
--- - name: Deploy session recording hosts: managed-node-01.example.com tasks: - name: Enable session recording for specific users ansible.builtin.include_role: name: rhel-system-roles.tlog vars: tlog_scope_sssd: some tlog_users_sssd: - <recorded_user>
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
cd /etc/sssd/conf.d/sssd-session-recording.conf
journalctl _COMM=tlog-rec-sessio Nov 12 09:17:30 managed-node-01.example.com -tlog-rec-session[1546]: {"ver":"2.3","host":"managed-node-01.example.com","rec":"07418f2b0f334c1696c10cbe6f6f31a6-60a-e4a2","user":"demo-user",
tlog-play -r journal -M TLOG_REC= <recording_id>
--- - name: Deploy session recording excluding users and groups hosts: managed-node-01.example.com tasks: - name: Exclude users and groups ansible.builtin.include_role: name: rhel-system-roles.tlog vars: tlog_scope_sssd: all tlog_exclude_users_sssd: - jeff - james tlog_exclude_groups_sssd: - admins
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
cat /etc/sssd/conf.d/sssd-session-recording.conf
journalctl _COMM=tlog-rec-sessio Nov 12 09:17:30 managed-node-01.example.com -tlog-rec-session[1546]: {"ver":"2.3","host":"managed-node-01.example.com","rec":"07418f2b0f334c1696c10cbe6f6f31a6-60a-e4a2","user":"demo-user",
tlog-play -r journal -M TLOG_REC= <recording_id>
- name: Host to host VPN hosts: managed-node-01.example.com, managed-node-02.example.com roles: - rhel-system-roles.vpn vars: vpn_connections: - hosts: managed-node-01.example.com: managed-node-02.example.com: vpn_manage_firewall: true vpn_manage_selinux: true
vpn_connections: - hosts: managed-node-01.example.com: <external_node> : hostname: <IP_address_or_hostname>
- name: Multiple VPN hosts: managed-node-01.example.com, managed-node-02.example.com roles: - rhel-system-roles.vpn vars: vpn_connections: - name: control_plane_vpn hosts: managed-node-01.example.com: hostname: 192.0.2.0 # IP for the control plane managed-node-02.example.com: hostname: 192.0.2.1 - name: data_plane_vpn hosts: managed-node-01.example.com: hostname: 10.0.0.1 # IP for the data plane managed-node-02.example.com: hostname: 10.0.0.2
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ipsec status | grep <connection_name>
ipsec trafficstatus | grep <connection_name>
ipsec auto --add <connection_name>
- name: Mesh VPN hosts: managed-node-01.example.com, managed-node-02.example.com, managed-node-03.example.com roles: - rhel-system-roles.vpn vars: vpn_connections: - opportunistic: true auth_method: cert policies: - policy: private cidr: default - policy: private-or-clear cidr: 198.51.100.0/24 - policy: private cidr: 192.0.2.0/24 - policy: clear cidr: 192.0.2.7/32 vpn_manage_firewall: true vpn_manage_selinux: true
ansible-playbook --syntax-check ~/playbook.yml
ansible-playbook ~/playbook.yml
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
sa_pwd: <sa_password>
--- - name: Installing and configuring Microsoft SQL Server hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: SQL Server with an existing private key and certificate ansible.builtin.include_role: name: microsoft.sql.server vars: mssql_accept_microsoft_odbc_driver_17_for_sql_server_eula: true mssql_accept_microsoft_cli_utilities_for_sql_server_eula: true mssql_accept_microsoft_sql_server_standard_eula: true mssql_version: 2022 mssql_password: "{{ sa_pwd }}" mssql_edition: Developer mssql_tcp_port: 1433 mssql_manage_firewall: true mssql_tls_enable: true mssql_tls_cert: sql_crt.pem mssql_tls_private_key: sql_cert.key mssql_tls_version: 1.2 mssql_tls_force: true
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
/opt/mssql-tools/bin/sqlcmd -N -S server.example.com -U "sa" -P <sa_password> -Q 'SELECT SYSTEM_USER'
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
sa_pwd: <sa_password>
--- - name: Installing and configuring Microsoft SQL Server hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: SQL Server with certificates issued by Red Hat IdM ansible.builtin.include_role: name: microsoft.sql.server vars: mssql_accept_microsoft_odbc_driver_17_for_sql_server_eula: true mssql_accept_microsoft_cli_utilities_for_sql_server_eula: true mssql_accept_microsoft_sql_server_standard_eula: true mssql_version: 2022 mssql_password: "{{ sa_pwd }}" mssql_edition: Developer mssql_tcp_port: 1433 mssql_manage_firewall: true mssql_tls_enable: true mssql_tls_certificates: - name: sql_cert dns: server.example.com ca: ipa
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
/opt/mssql-tools/bin/sqlcmd -N -S server.example.com -U "sa" -P <sa_password> -Q 'SELECT SYSTEM_USER'
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
sa_pwd: <sa_password>
--- - name: Installing and configuring Microsoft SQL Server hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: SQL Server with custom storage paths ansible.builtin.include_role: name: microsoft.sql.server vars: mssql_accept_microsoft_odbc_driver_17_for_sql_server_eula: true mssql_accept_microsoft_cli_utilities_for_sql_server_eula: true mssql_accept_microsoft_sql_server_standard_eula: true mssql_version: 2022 mssql_password: "{{ sa_pwd }}" mssql_edition: Developer mssql_tcp_port: 1433 mssql_manage_firewall: true mssql_datadir: /var/lib/mssql/ mssql_datadir_mode: '0700' mssql_logdir: /var/log/mssql/ mssql_logdir_mode: '0700'
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
ansible managed-node-01.example.com -m command -a 'ls -ld /var/lib/mssql/' drwx------. 12 mssql mssql 4096 Jul 3 13:53 /var/lib/mssql/
ansible managed-node-01.example.com -m command -a 'ls -ld /var/log/mssql/' drwx------. 12 mssql mssql 4096 Jul 3 13:53 /var/log/mssql/
ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
sa_pwd: <sa_password> sql_pwd: <SQL_AD_password> ad_admin_pwd: <AD_admin_password>
--- - name: Installing and configuring Microsoft SQL Server hosts: managed-node-01.example.com vars_files: - vault.yml tasks: - name: SQL Server with AD authentication ansible.builtin.include_role: name: microsoft.sql.server vars: mssql_accept_microsoft_odbc_driver_17_for_sql_server_eula: true mssql_accept_microsoft_cli_utilities_for_sql_server_eula: true mssql_accept_microsoft_sql_server_standard_eula: true mssql_version: 2022 mssql_password: "{{ sa_pwd }}" mssql_edition: Developer mssql_tcp_port: 1433 mssql_manage_firewall: true mssql_ad_configure: true mssql_ad_join: true mssql_ad_sql_user: sqluser mssql_ad_sql_password: "{{ sql_pwd }}" ad_integration_realm: ad.example.com ad_integration_user: Administrator ad_integration_password: "{{ ad_admin_pwd }}"
ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
ansible-playbook --ask-vault-pass ~/playbook.yml
C:\> Set-ADUser -Identity sqluser -KerberosEncryptionType AES128,AES256
kinit Administrator@ad.example.com
/opt/mssql-tools/bin/sqlcmd -S. -Q 'CREATE LOGIN [AD\<AD_user>] FROM WINDOWS;'
kinit <AD_user> @ad.example.com
/opt/mssql-tools/bin/sqlcmd -S. -Q 'SELECT SYSTEM_USER'