In todays post I am going to share an ansible playbook to configure a new VM recently launched. This playbook contains the following:
- Change Admin password
- Create linux Group
- Add user to several groups
- Create a new user with specific salted password (Check point 3 for generating the hashed salt)
- Find all the mounted disks in any LUN and format them (create a xfs filesystem)
- Create a mountpoint (in /opt)
- Mount the disk formatted in LUN 0 PART 1 in the specified mountoint in fstab, so it will be persistent across reboots
- Register the OS into RHEL Satellite so yum is usable
- Disable some local repo in an external /mnt drive that crashes yum in the image
- Install Telnet and other packages
- Modify some Ulimits
- Register Machine in a domain (TO BE DONE)
To Start, lets create first the ansible inventory file and call it inventory.yaml (Or use init format if you want). The format of the file should be something like the folowing:
all:
children:
myservers:
hosts:
SERVER001:
ansible_host: 10.10.1.1
SERVER002:
ansible_host: 10.10.1.2
SERVER003:
ansible_host: 10.10.1.3
SERVER004:
ansible_host: 10.10.1.4
SERVER005:
ansible_host: 10.10.1.5
alberttest:
hosts:
testalbert001:
ansible_host: 10.10.1.6
Then we can create our playbook file (I will comment it below). This will be another yaml file with the following content:
---
- hosts: myservers
collections:
- ansible.posix
tasks:
- name: Ping the Server
ping:
- name: Change Password of the Admin user.
user:
name: Admin
# python3 -c 'import crypt; print (crypt.crypt("Passw0rd", "$1$SomeSalt$"))'
password: $1$SomeSalt$C7s11A7tyf8OKOg0JoCYp/
- name: Create anogues group
group:
name: anogues
state: present
- name: Create anogues user
user:
name: anogues
password: $1$SomeSalt$C7s11A7tyf8OKOg0JoCYp/
shell: /bin/bash
groups: infaedc, wheel
append: yes
- name: Create mountpoint
file: path=/opt/data state=directory
- name: Find all Luns
find:
paths: /dev/disk/azure/scsi1/
file_type: link
recurse: No
patterns: "lun?"
register: files_matched
- name: Partition Disk to Max
shell: "parted {{ item.path }} --script mklabel gpt mkpart xfspart xfs 0% 100%"
args:
executable: /bin/bash
loop: "{{ files_matched.files|flatten(levels=1) }}"
- name: Inform OS of partition table changes
command: partprobe
- name: find UUID of sdX1
shell: |
blkid -s UUID -o value $(readlink -f /dev/disk/azure/scsi1/lun0-part1)
register: uuid
- name: show real uuid
debug:
msg: "{{ uuid.stdout }}"
- name: Mount disk drive in fstab
mount:
path: /opt/data
src: 'UUID={{uuid.stdout}}'
fstype: xfs
opts: defaults,nofail
dump: 1
passno: 2
state: mounted
- name: Check disk Status
shell: df -h | grep /dev/sd
register: df2_status
- name: Show mounted FS
debug:
msg: "{{ df2_status.stdout_lines }}"
- name: Register RHEL
redhat_subscription:
state: present
username: {{ lookup('env', 'RHEL_USER') }}
password: {{ lookup('env', 'RHEL_PASSWORD') }}
autosubscribe: yes
- name: Disable Media Repo
ini_file:
dest: /etc/yum.repos.d/media.repo
section: "{{item}}"
option: enabled
value: 0
with_items:
- LocalRepo_BaseOS
- LocalRepo_AppStream
- name: Install Telnet and other packags
yum:
name:
- telnet
- curl
- zip
- unzip
- tar
- wget
- libcurl
state: present
- name: Add or modify nproc hard limit for the user anogues. Set 65k value.
pam_limits:
domain: anogues
limit_type: hard
limit_item: nproc
value: 65000
become: yes
become_method: sudo
become_user: root
- name: Add or modify nproc soft limit for the user anogues. Set 65k value.
pam_limits:
domain: anogues
limit_type: soft
limit_item: nproc
value: 65000
become: yes
become_method: sudo
become_user: root
Let’s have a look at how it works:
One of the playbook steps is to register RHEL into Satellite. To avoid hardcoding the user and password in the playbooy these values will be taken from your env vars, so please export them before
export RHEL_USER=
export RHEL_PASSWORD=
You need to install ansible-posix first (Tested with 1.2.0.). Download it from here: https://galaxy.ansible.com/ansible/posix
ansible-galaxy install ansible-posix-1.2.0.tar.gz
To create a crypted user with a salt you can do the following
python3 -c ‘import crypt; print (crypt.crypt(“YOUR_UNHASHED_PASSWORD”, “$1$SomeSalt$”))’
And copy the hashed salt into the playbook area for the user you want to set the password
Azure Mounts the Disk Drives by Luns. By default it starts in Lun0, So i am using the softlink to /dev/disk/azure to check the disks added. This playbook will only automount the first disk. If you need more simply modify the playbook and add as many luns as you need
# tree /dev/disk/azure
/dev/disk/azure
├── resource -> ../../sdb
├── resource-part1 -> ../../sdb1
├── root -> ../../sda
├── root-part1 -> ../../sda1
├── root-part14 -> ../../sda14
├── root-part15 -> ../../sda15
├── root-part2 -> ../../sda2
└── scsi1
├── lun0 -> ../../../sdc
└── lun1 -> ../../../sdd
Here there are two disks mounted in two luns, 0 and 1. No disk has been formatted yet as we only see sdc and sdd drives with no partition. Once the first one is formatted, you will see a difference:
/dev/disk/azure
├── resource -> ../../sdb
├── resource-part1 -> ../../sdb1
├── root -> ../../sda
├── root-part1 -> ../../sda1
├── root-part14 -> ../../sda14
├── root-part15 -> ../../sda15
├── root-part2 -> ../../sda2
└── scsi1
├── lun0 -> ../../../sdc
├── lun0-part1 -> ../../../sdc1
└── lun1 -> ../../../sdd
To run it (make sure you have installed ansible 2.9 from RHEL repo):
ansible-playbook -i inventory.yaml -k playbook.yaml
The playbook also formats all drives found in any luns (All disks mounted in the VM), bout only mounts the first one as we only defined one mount point.
If we need to modify it, we can include all the tasks that ar enecessary (read the blkid, add entry in fstab into another loop block but previously we have to create as many directories for the mountpoints as necessay and feed them in the loop block, so they are assigned concurrently.
Links of interest:
https://stackoverflow.com/questions/19292899/creating-a-new-user-and-password-with-ansible