322 lines
8.4 KiB
Markdown
322 lines
8.4 KiB
Markdown
# Automation with Ansible
|
|
Demonisioning: web01, nmon-01, docker-01 😢
|
|
___
|
|
## New Machines
|
|
### controller-charlotte - Ubuntu
|
|
configure with netplan
|
|
```
|
|
network:
|
|
ethernets:
|
|
ens160:
|
|
dhcp4: no
|
|
addresses:
|
|
- 10.0.5.90/24
|
|
routes:
|
|
- to: default
|
|
via: 10.0.5.2
|
|
nameservers:
|
|
addresses:
|
|
- 10.0.5.5
|
|
version: 2
|
|
```
|
|
#### to reset DNS
|
|
```
|
|
dhclient -r
|
|
dhclient
|
|
```
|
|
### ansible1-charlotte - CentOS
|
|
configure with nmtui
|
|
- IP: 10.0.5.91
|
|
- DG: 10.0.5.2
|
|
- DNS: 10.0.5.5
|
|
### ansible2-charlotte - CentOS
|
|
configure with nmtui
|
|
- IP: 10.0.5.92
|
|
- DG: 10.0.5.2
|
|
- DNS: 10.0.5.5
|
|
|
|
## Initial Configuration
|
|
- on all machines, create a sudo account named deployer (use same password across all systems)
|
|
- install ansible on controller
|
|
```
|
|
sudo apt install ansible sshpass python3-paramiko
|
|
```
|
|
- Configure sudo access:
|
|
- create `/etc/sudoers.d/sys265` on all systems
|
|
- add the following line to allow passwordless sudo for deployer:
|
|
```
|
|
deployer ALL=(ALL) NOPASSWD:ALL
|
|
```
|
|
|
|
> [!Note]
|
|
> Although it is not uncommon to update `/etc/sudoers` directly, it is far easier to script the addition of a file to `/etc/sudoers.d`
|
|
|
|
|
|
## SSH Key Setup
|
|
As the deployer user on controller:
|
|
- Create RSA keypair with passphrase:
|
|
```
|
|
ssh-keygen -t rsa
|
|
```
|
|
- copy pukey to ansible1 and ansible2
|
|
```
|
|
ssh-copy-id deployer@ansible1-charlotte
|
|
ssh-copy-id deployer@ansible2-charlotte
|
|
```
|
|
-configure `ssh-agent` to avoid typing passphrase for 4 hours
|
|
```
|
|
eval(ssh-agent) # test to see if ssh-agent is running, and if not,run it
|
|
ssh-add -t 14400
|
|
```
|
|
## Ansible Configuration
|
|
in `deployer@controller:/home/deployer/`
|
|
- make directory structure
|
|
```
|
|
mkdir -p ansible/roles
|
|
cd ansible/
|
|
```
|
|
- create inventory and test conection
|
|
```
|
|
echo ansible1-charlotte >> inventory.txt
|
|
echo ansible2-charlotte >> inventory.txt
|
|
cat inventory.txt
|
|
```
|
|
```
|
|
ansible all -m ping -i inventory.txt
|
|
```
|
|
|
|
- add webmin tag to `inventory.txt` and test
|
|
|
|
```
|
|
ansible1-charlotte
|
|
[webmin]
|
|
ansible2-charlotte
|
|
```
|
|
|
|
```
|
|
deployer@controller-charlotte:~/ansible$ ansible webmin -m ping -i inventory.txt
|
|
ansible2-charlotte | SUCCESS => {
|
|
"ansible_facts": {
|
|
"discovered_interpreter_python": "/usr/libexec/platform-python"
|
|
},
|
|
"changed": false,
|
|
"ping": "pong"
|
|
}
|
|
```
|
|
|
|
## webmin installation
|
|
- install webmin role
|
|
```
|
|
ansible-galaxy install semuadmin.webmin -p roles/
|
|
```
|
|
- create `webmin.yml` playbook to handle repository setup, installation, and firewall configuration
|
|
```
|
|
- name: webmin sys265
|
|
hosts: webmin
|
|
become: true # Run all tasks with sudo/root privileges
|
|
vars:
|
|
install_utilities: false
|
|
firewalld_enable: true
|
|
|
|
pre_tasks: # before role execution. we need the repo/key before executing webmin installation role
|
|
- name: add webmin repo and GPG key
|
|
yum_repository:
|
|
name: webmin
|
|
description: Webmin Distribution Neutral
|
|
baseurl: http://download.webmin.com/download/yum
|
|
enabled: true
|
|
gpgcheck: true
|
|
gpgkey: http://www.webmin.com/jcameron-key.asc
|
|
|
|
# update YUM cache to recognize new repository
|
|
- name: clean and update YUM cache
|
|
yum:
|
|
update_cache: yes
|
|
|
|
roles:
|
|
- semuadmin.webmin # apply the webmin installation role
|
|
|
|
handlers: # will run when a task has notify:name parameter
|
|
- name: reload firewall # runs after adding firewall rule
|
|
command: firewall-cmd --reload
|
|
|
|
tasks:
|
|
# open port 10000 in firewall for webmin web interface
|
|
- name: add firewall rule
|
|
firewalld:
|
|
port: 10000/tcp
|
|
permanent: true
|
|
state: enabled
|
|
notify: reload firewall
|
|
|
|
- name: install webmin
|
|
yum:
|
|
name: webmin
|
|
state: present # will only install if not already
|
|
|
|
- name: enable and start webmin service
|
|
systemd:
|
|
name: webmin
|
|
enabled: true
|
|
state: started
|
|
daemon_reload: yes # reload systemd to recognize new service
|
|
```
|
|
- run playbook
|
|
```
|
|
ansible-playbook -i inventory.txt roles/webmin.yml
|
|
```
|
|
- change webmin root password
|
|
```
|
|
sudo /usr/libexec/webmin/changepass.pl /etc/webmin root newpassword
|
|
```
|
|
|
|
|
|
## apache isntallation
|
|
- edit inventory.txt
|
|
```
|
|
[apache]
|
|
ansible1-charlotte
|
|
[webmin]
|
|
ansible2-charlotte
|
|
```
|
|
- install apache role
|
|
```
|
|
ansible-galaxy install geerlingguy.apache -p roles/
|
|
```
|
|
- create `apache.yml` file
|
|
```
|
|
- name: apache sys265
|
|
hosts: apache
|
|
become: true # Run all tasks with sudo/root privileges
|
|
vars:
|
|
install_utilities: false
|
|
firewalld_enable: true
|
|
ansible_os_family: RedHat
|
|
ansible_distribution: CentOS # required because role searches for Rocky config files
|
|
roles:
|
|
- geerlingguy.apache # apply the apache installation role
|
|
|
|
handlers: # will run when a task has notify:name parameter
|
|
- name: reload firewall # runs after adding firewall rule
|
|
command: firewall-cmd --reload
|
|
|
|
tasks:
|
|
# open port 443 in firewall for apache web interface
|
|
- name: add firewall rule
|
|
firewalld:
|
|
port: "{{ item }}"
|
|
permanent: true
|
|
immediate: true
|
|
state: enabled
|
|
loop:
|
|
- 80/tcp
|
|
- 443/tcp
|
|
notify: reload firewall
|
|
|
|
- name: install apache
|
|
yum:
|
|
name: httpd
|
|
state: present # will only install if not already
|
|
|
|
- name: enable and start apache service
|
|
systemd:
|
|
name: httpd
|
|
enabled: true
|
|
state: started
|
|
daemon_reload: yes # reload systemd to recognize new service
|
|
|
|
```
|
|
- run playbook
|
|
```
|
|
ansible-playbook -i inventory.txt roles/webmin.yml
|
|
```
|
|
|
|
# Ansible on Windows
|
|
## OpenSSH Server Setup
|
|
|
|
>[!Caution]
|
|
> DO NOT INSTALL 32 BIT VERSION
|
|
|
|
### Install OpenSSH
|
|
Run these commands in PowerShell as Administrator:
|
|
```
|
|
wget https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.8.1.0p1-Preview/OpenSSH-Win64.zip -O 'C:\Program Files\OpenSSH.zip'
|
|
Expand-Archive -Path 'C:\Program Files\OpenSSH.zip' -DestinationPath 'C:\Program Files\OpenSSH'
|
|
rm 'C:\Program Files\OpenSSH.zip'
|
|
powershell.exe -ExecutionPolicy Bypass -File 'C:\Program Files\OpenSSH\OpenSSH-Win64\install-sshd.ps1'
|
|
```
|
|
### Configure OpenSSH
|
|
- start service
|
|
```
|
|
Start-Service sshd
|
|
Set-Service -Name sshd -StartupType 'Automatic'
|
|
Get-Service -Name sshd # check if running
|
|
```
|
|
- add firewall rule
|
|
```
|
|
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
|
|
Get-NetFirewallRule | Where-Object DisplayName -Like '*ssh*'
|
|
```
|
|
- set PowerShell as default SSH shell
|
|
```
|
|
Set-ItemProperty "HKLM:\Software\Microsoft\Powershell\1\ShellIds" -Name ConsolePrompting -Value $true
|
|
New-ItemProperty -Path HKLM:\SOFTWARE\OpenSSH -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
|
|
```
|
|
- add `charlotte.croce-adm` to the **Remote Management Users** groups
|
|
- Add/uncomment the following lines in C:\ProgramData\ssh\sshd_config
|
|
- `StrictModes no` is sometimes needed on Windows systems because Windows permissions don't map perfectly to the UNIX-style permissions that OpenSSH expects
|
|
```
|
|
AllowUsers charlotte\charlotte.croce-adm
|
|
StrictModes no
|
|
```
|
|
## Ansible Setup
|
|
### Inventory Setup
|
|
- add windows machines to `inventory.txt`
|
|
```
|
|
[windows]
|
|
mgmt01-charlotte
|
|
wks01-charlotte
|
|
[windows:vars]
|
|
ansible_shell_type=powershell
|
|
```
|
|
- create ansible.cfg in ansible directory, to skip host key checking
|
|
```
|
|
[defaults]
|
|
host_key_checking = false
|
|
```
|
|
- test connection
|
|
```
|
|
ansible windows -i inventory.txt -m win_ping -u charlotte.croce-adm@charlotte.local --ask-pass
|
|
```
|
|
|
|
## Software deployment using win_chocolatey
|
|
- create playbook `roles/windows_software.yml`
|
|
```
|
|
- name: install windows applications
|
|
hosts: windows
|
|
tasks:
|
|
- name: install firefox and 7zip
|
|
win_chocolatey:
|
|
name:
|
|
- firefox
|
|
- 7zip
|
|
state: present
|
|
```
|
|
- run playbook
|
|
```
|
|
ansible-playbook -i inventory.txt roles/windows_software.yml -u charlotte.croce-adm@charlotte.local --ask-pass
|
|
```
|
|
- If you encounter .NET Framework errors, install version 4.8 (in my case I needed version 4.8, it will probably be a different version in the future)
|
|
```
|
|
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2088631" -OutFile "C:\dotNetFx48.exe"
|
|
Start-Process -FilePath "C:\dotNetFx48.exe" -ArgumentList "/quiet /norestart" -Wait
|
|
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release # verify installation
|
|
```
|
|
> [!Note]
|
|
> Installation may take several minutes. System restart required after installation.
|
|
|
|
- list packages installed with chocolatey
|
|
```
|
|
'C:\ProgramData\chocolatey\bin\choco.exe' list
|
|
```
|
|
|