:::success
## RHCE解題流程
:::
## Q1 安裝和設定 ANSIBLE
1.下載ansible
```*=
sudo dnf install ansible-core -y
```
2.建立目錄
```*=
[student@control ~]$ mkdir ansible
[student@control ~]$ cd ansible/
[student@control ansible]$ touch inventory
[student@control ansible]$ mkdir mycollections
[student@control ansible]$ mkdir roles
```
3.編輯inventory
```*=
[dev]
node1
[test]
node2
[prod]
node[3:4]
[balancers]
node5
[webservers:children]
prod
```
**4.檢查inventory**
```*=
[student@control ansible]$ ansible all -i inventory --list-hosts
hosts (5):
node1
node2
node5
node3
node4
[student@control ansible]$ ansible webservers -i inventory --list-hosts
hosts (2):
node3
node4
[student@control ansible]$ ansible balancers -i inventory --list-hosts
hosts (1):
node5
[student@control ansible]$ ansible prod -i inventory --list-hosts
hosts (2):
node3
node4
[student@control ansible]$ ansible test,dev -i inventory --list-hosts
hosts (2):
node2
node1
```
5.編輯ansible.cfg
```=
[student@control ansible]$ vim /etc/ansible/ansible.cfg
```
**複製 $ ansible-config init > ansible.cfg_init
查看裡面內容如何撰寫ansible.cfg**
```*=
[student@control ansible]$ touch ansible.cfg
[student@control ansible]$ vim ansible.cfg
[defaults]
inventory = inventory
remote_user = student
collections_path = mycollections
roles_path = roles
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
```
**6.檢查ansible.cfg**
```*=
[student@control ansible]$ ansible all -m ping
```
## Q2 建立 YUM 軟體(REPOSITORY)
1.編輯yum_repo.yml
```*=
[student@control ansible]$ touch yum_repo.yml
[student@control ansible]$ vim yum_repo.yml
---
- name: q2
hosts: all
tasks:
- name: BASE
yum_repository:
name: "EX294_BASE"
description: "EX294 base software"
baseurl: "http://data.example.com/rhel9/BaseOS"
gpgcheck: yes
gpgkey: "http://data.example.com/rhel9/RPM-GPG-KEY-redhat-release"
enabled: yes
- name: STREAM
yum_repository:
name: "EX294_STREAM"
description: "EX294 stream software"
baseurl: "http://data.example.com/rhel9/AppStream"
gpgcheck: yes
gpgkey: "http://data.example.com/rhel9/RPM-GPG-KEY-redhat-release"
enabled: yes
...
```
2.執行yum_repo.yml
```=
[student@control ansible]$ ansible-playbook yum_repo.yml
```
**3.檢查repo安裝**
```
[student@control ansible]$ ansible all -m shell -a 'yum repolist'
```
## Q3 安裝集合(COLLECTION)
1.在collecitons目錄建立requirements.yml
```*=
[student@control mycollections]$ pwd
/home/student/ansible/mycollections
[student@control mycollections]$ touch requirements.yml
[student@control mycollections]$ vim requirements.yml
---
collections:
- http://data.example.com/materials/redhat-rhel_system_roles-1.16.2.tar.gz
- http://data.example.com/materials/ansible-posix-1.4.0.tar.gz
- http://data.example.com/materials/community-general-7.1.0.tar.gz
...
```
2.執行ansible-galaxy collection
```*=
[student@control ansible]$ ansible-galaxy collection install -r
mycollections/requirements.yml
```
**3.檢查下載collection**
```*=
[student@control mycollections]$ ll
total 4
drwxrwxr-x. 5 student student 52 Dec 10 05:03 ansible_collections
-rw-rw-r--. 1 student student 233 Dec 10 05:00 requirements.yml
```
## Q4 安裝軟體包
1.編輯packages.yml
```*=
[student@control ansible]$ touch packages.yml
[student@control ansible]$ vim packages.yml
---
- name: q4
hosts: dev,test,prod
tasks:
- name: 1. install php , mariadb
dnf:
name: "{{ item }}"
state: present
loop:
- php
- mariadb
- name: 2. install RPM Development Tools
dnf:
name: '@RPM Development Tools'
state: present
when:
- ansible_facts.fqdn == "node1.example.com"
- name: 3. latest
dnf:
name: "*"
state: latest
when:
- ansible_facts.fqdn == "node1.example.com"
...
```
2.執行 packages.yml
```*=
[student@control ansible]$ ansible-playbook packages.yml
```
**3.檢查下載安裝包**
```*=
[student@control ansible]$ ansible node1 -m shell -a 'dnf list | grep mariadb'
[student@control ansible]$ ansible node1 -m shell -a 'dnf list | grep php'
```
## Q5.A 使用RHEL系統角色 timesync
1.建立timesync.yml
```*=
[student@control ansible]$ touch timesync.yml
```
2.下載ansible_collections中的timesync到roles目錄中
```*=
[student@control ansible]$ cd roles/
[student@control roles]$ cp -rp /home/student/ansible/mycollections/ansible_collections/redhat/rhel_system_roles/roles/timesync .
[student@control roles]$ ll
total 0
drwxr-xr-x. 8 student student 109 Dec 10 05:03 timesync
```
3.編輯timesync.yml
```=
[student@control ansible]$ vim timesync.yml
---
- name: timesync
hosts: all
vars:
timesync_ntp_servers:
- hostname: 172.24.1.254
iburst: yes
roles:
- timesync
...
```
**4.檢查chronyd服務**
```*=
[student@control ansible]$ ansible node1 -m shell -a 'chronyc source -v'
[student@control ansible]$ ansible node1 -m shell -a 'systemctl status chronyd'
```
## Q5.B 使用RHEL系統角色 Selinux
1.建立selinux.yml
```*=
[student@control ansible]$ touch selinux.yml
```
2.下載ansible_collections中的selinux到roles目錄中
```*=
[student@control ansible]$ cd roles/
[student@control roles]$ cp -rp /home/student/ansible/mycollections/ansible_collections/redhat/rhel_system_roles/roles/selinux/ .
```
3.編輯selinux.yml
```*=
[student@control ansible]$ vim selinux.yml
---
- name: selinux
hosts: all
vars:
selinux_policy: targeted
selinux_state: enforcing
roles:
- selinux
...
```
4.執行selinux.yml
```*=
[student@control ansible]$ ansible-playbook selinux.yml
```
**5.檢查selinux**
```*=
[student@control ansible]$ ansible all -m shell -a 'getenforce'
[student@control ansible]$ ansible all -m shell -a 'sestatus'
```
## Q6 使用ANSIBLE GALAXY安裝角色
1.在roles目錄建立requirements.yml
```*=
[student@control roles]$ touch requirements.yml
```
2.編輯requirements.yml
```*=
[student@control roles]$ vim requirements.yml
---
- name: balancer
src: "http://data.example.com/materials/haproxy.tar"
- name: phpinfo
src: "http://data.example.com/materials/phpinfo.tar"
```
3.執行ansible-galaxy role
```*=
[student@control ansible]$ ansible-galaxy role install -r roles/requirements.yml
```
**4.檢查下載的roles角色**
```*=
[student@control roles]$ ll
total 4
drwxrwxr-x. 9 student student 122 Jan 8 12:30 balancer
drwxrwxr-x. 9 student student 122 Jan 8 12:30 phpinfo
-rw-rw-r--. 1 student student 147 Jan 8 12:30 requirements.yml
drwxr-xr-x. 7 student student 114 Jan 8 12:13 selinux
drwxr-xr-x. 8 student student 109 Jan 8 11:59 timesync
```
## Q7 建立並使用角色
1.在roles目錄中建立角色
```*=
[student@control roles]$ ansible-galaxy init apache
- Role apache was created successfully
```
2.在apache目錄中的tasks目錄撰寫yml任務
```*=
[student@control tasks]$ vim main.yml
---
# tasks file for apache
- name: 1. Start firewalld
systemd:
name: firewalld
state: started
enabled: yes
- name: 2. Install httpd
dnf:
name: httpd
state: present
- name: 3. Open Firewalld Service
firewalld:
service: http
state: enabled
immediate: yes
permanent: yes
- name: 4. Start Service
systemd:
name: httpd
state: started
enabled: yes
- name: 5. use template
template:
src: "index.html.j2"
dest: "/var/www/html/index.html"
force: yes
```
3.在apache目錄中的template目錄撰寫index.html.j2
```*=
[student@control templates]$ touch index.html.j2
[student@control templates]$ vim index.html.j2
Welcome to {{ ansible_facts.fqdn }} on {{ ansible_facts.default_ipv4.address }}
```
4.編輯newnole.yml
```*=
[student@control ansible]$ touch newrole.yml
[student@control ansible]$ vim newrole.yml
---
- name: q7
hosts: webservers
roles:
- apache
...
```
5.執行newrole.yml
```*=
[student@control ansible]$ ansible-playbook newrole.yml
```
## Q8 使用ANSIBLE GALAXY的角色
1.編輯roles.yml
```*=
---
- name: use phpinfo
hosts: webservers
roles:
- phpinfo
- name: use balancer
hosts: balancers
roles:
- balancer
...
```
**phpinfo的任務要先執行,否則執行會失敗**
2.執行roles.yml
```*=
[student@control ansible]$ ansible-playbook roles.yml
```
3.檢查
```*=
開啟網頁網址輸入 http://node5.example.com
按住f5確認有在node3及node4之間切換
開啟網頁網址輸入 http://node3.example.com/hello.php
確認有php首頁
```
## Q9 (舊)建立並使用邏輯卷宗
1.編輯lvm.yml
```*=
[student@control ansible]$ touch lvm.yml
[student@control ansible]$ vim lvm.yml
---
- name: Create lvm
hosts: all
tasks:
- name: 1. look lvm
debug:
msg: "Volume group does not exist"
when: ansible_facts.lvm.vgs.research is not defined
- block:
- name: 1.1 Create Data 1500M
lvol:
vg: "research"
lv: "data"
size: 1500M
state: present
notify:
- mkfs
ignore_errors: no
when: ansible_facts.lvm.vgs.research is defined
rescue:
- name: 2.1 look lvm
debug:
msg: "Could not create logical volume of that size"
- name: 2.2 Create Data 800M
lvol:
vg: "research"
lv: "data"
size: 800M
state: present
notify:
- mkfs
ignore_errors: yes
handlers:
- name: mkfs
filesystem:
fstype: ext4
dev: "/dev/research/data"
```
2.執行lvm.yml
```*=
[student@control ansible]$ ansible-playbook lvm.yml
```
**3.lsblk檢查**
```*=
[student@control ansible]$ ansible node1 -m shell -a 'lsblk'
(包含host的device資訊)
```
## Q9. (新)建立並使用磁碟分割區 part.yml
1.編輯part.yml
```*=
[student@control ansible]$ touch part.yml
[student@control ansible]$ vim part.yml
---
- name: now q9 sdb
hosts: balancers
tasks:
- name: 1.1 parted not defined
debug:
msg: "Disk does not exist"
when: ansible_facts.devices.vdd is not defined
- block:
- name: 1.2 Crate Parted 1500
parted:
device: "{{ item }}"
label: msdos
part_type: primary
number: 1
part_start: 1MiB
part_end: 1500MiB
state: present
loop:
- /dev/sdb
- /dev/sdc
notify:
- mkfs
- mkdir
- mount
rescue:
- name: 1.3 not create partition
debug:
msg: "Could not create partition of that size"
- name: 1.4 Crate Parted 800
parted:
device: /dev/sdc
label: msdos
part_type: primary
number: 1
part_start: 1MiB
part_end: 800MiB
state: present
notify:
- mkfs
- mkdir
- mount
handlers:
- name: mkfs
filesystem:
fstype: ext4
dev: "{{ item }}"
loop:
- /dev/sdb1
- /dev/sdc1
- name: mkdir
file:
path: "{{ item }}"
mode: "0755"
state: directory
loop:
- /newpart
- /newpart1
- name: mount
mount:
src: "{{ item.dev_src }}"
path: "{{ item.dev_path }}"
fstype: ext4
state: mounted
loop:
- dev_src: /dev/sdb1
dev_path: /newpart
- dev_src: /dev/sdc1
dev_path: /newpart1
...
```
2.執行part.yml
```*=
[student@control ansible]$ ansible-playbook part.yml
```
**3.檢查是否掛接及分割區大小**
```*=
[student@control ansible]$ ansible all -m shell -a 'lsblk'
[student@control ansible]$ ansible all -m shell -a 'cat /etc/'
```
## Q10 產生HOSTS文件
1.下載host.j2跟hosts.yml的模板
```*=
[student@control ansible]$ wget http://data.example.com/materials/hosts.j2
[student@control ansible]$ wget http://data.example.com/materials/hosts.yml
```
2.編輯 host.j2
```*=
vim hosts.j2
-------------
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for host in groups['all'] %}
{{ hostvars[host].ansible_facts.default_ipv4.address }} {{ hostvars[host].ansible_facts.fqdn }} {{ hostvars[host].ansible_facts.hostname }}
{% endfor %}
```
3.執行hosts.yml
```*=
[student@control ansible]$ ansible-playbook hosts.yml
```
**4.檢查**
```*=
[student@control ansible]$ ansible dev -m shell -a 'cat /etc/myhosts'
```
## Q11 修改文件內容
1.建立group_vars目錄
```*=
[student@control ansible]$ mkdir group_vars
```
2.將特定主機所需文字內容echo到group_vars目錄中特定主機的變數yml
```*=
[student@control ansible]$ echo 'message: "Development"' >> group_vars/dev.yml
[student@control ansible]$ echo 'message: "Test"' >> group_vars/test.yml
[student@control ansible]$ echo 'message: "Production"' >> group_vars/prod.yml
```
3.編輯issue.yml
```*=
[student@control ansible]$ touch issue.yml
[student@control ansible]$ vim issue.yml
---
- name: q11
hosts: all
tasks:
- name: 1. wirte Development
copy:
content: "{{ message }}"
dest: "/etc/issue"
ignore_errors: yes
...
```
**4.檢查/etc/issue**
```*=
[student@control ansible]$ ansible all -m shell -a 'cat /etc/issue'
node3 | CHANGED | rc=0 >>
Production
node5 | CHANGED | rc=0 >>
\S
Kernel \r on an \m
node2 | CHANGED | rc=0 >>
Test
node4 | CHANGED | rc=0 >>
Production
node1 | CHANGED | rc=0 >>
Development
```
## Q12 建立網站內容目錄
1.編輯webcontent.yml
```*=
[student@control ansible]$ touch webcontent.yml
[student@control ansible]$ vim webcontent.yml
---
- name: Webcontent
hosts: dev
tasks:
- name: 1. Install httpd
dnf:
name: httpd
state: present
- name: 2. Open Firewalld Service
firewalld:
service: http
state: enabled
immediate: yes
permanent: yes
- name: 3. Start Service
systemd:
name: httpd
state: started
enabled: yes
- name: 4. Create Group
group:
name: webdev
state: present
- name: 5. Create Directory
file:
path: "/webdev"
group: webdev
mode: '2775'
setype: httpd_sys_content_t
state: directory
- name: 6. Write Development
copy:
content: "Development"
dest: "/webdev/index.html"
group: webdev
setype: httpd_sys_content_t
- name: 7. Symbolic link
file:
src: "/webdev"
dest: "/var/www/html/webdev"
mode: '2775'
owner: root
group: webdev
state: link
...
```
2.執行 webcontent.yml
```*=
[student@control ansible]$ ansible-playbook webcontent.yml
```
**3.檢查webcontent**
```*=
[student@control ansible]$ ansible node1 -m shell -a
'curl http://node1.example.com/webdev/'
node1 | CHANGED | rc=0 >>
Development % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 11 100 11 0 0 2200 0 --:--:-- --:--:-- --:--:-- 2750
或者
登入網頁,網址列輸入 http://node1.example.com/webdev
```
## Q13 產生硬體報告
1.wget 下載http://data.example.com/materials/hwreport.empty 當作範本參考內容
```*=
[student@control ansible]$ wget http://data.example.com/materials/hwreport.empty
--2024-01-09 08:36:42-- http://data.example.com/materials/hwreport.empty
Resolving data.example.com (data.example.com)... 172.24.1.254
Connecting to data.example.com (data.example.com)|172.24.1.254|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 135
Saving to: ‘hwreport.empty’
hwreport.empty 100%[===================>] 135 --.-KB/s in 0s
2024-01-09 08:36:42 (20.4 MB/s) - ‘hwreport.empty’ saved [135/135]
# Hardware report
HOST=inventoryhostname
MEMORY=memory_in_MB
BIOS=BIOS_version
DISK_SIZE_VDA=disk_vda_size
DISK_SIZE_VDB=disk_vdb_size
```
2.編輯 hwreport.yml
- host查詢: ansible node1 -m setup -a 'filter=ansible_fqdn*'
- memory查詢: ansible node1 -m setup -a 'filter=ansible_mem*'
- bios查詢: ansible node1 -m setup -a 'filter=ansible_bios*'
- vda查詢: ansible node1 -m setup -a 'filter=ansible_device*'
- vdb查詢: ansible node1 -m setup -a 'filter=ansible_device*'
```*=
[student@control ansible]$ touch hwreport.yml
[student@control ansible]$ vim hwreport.yml
---
- name: q13
hosts: all
vars:
sfile: /root/hwreport.txt
host: "{{ ansible_facts.fqdn }}"
mem: "{{ ansible_facts.memtotal_mb }}"
bios: "{{ ansible_facts.bios_version }}"
vdasize: "{{ ansible_facts.devices.sda.size if ansible_facts.devices.sda.size is defined else 'NONE' }}"
vdbsize: "{{ ansible_facts.devices.sdb.size if ansible_facts.devices.sdb.size is defined else 'NONE' }}"
tasks:
- name: 1. install
get_url:
url: http://data.example.com/materials/hwreport.empty
dest: "{{ sfile }}"
force: yes
- name: 2. host
replace:
path: "{{ sfile }}"
regexp: inventoryhostname
replace: "{{ host }}"
- name: 3. mem
replace:
path: "{{ sfile }}"
regexp: memory_in_MB
replace: "{{ mem }}"
- name: 4. bios
replace:
path: "{{ sfile }}"
regexp: BIOS_version
replace: "{{ bios }}"
- name: 5. vdasize
replace:
path: "{{ sfile }}"
regexp: disk_vda_size
replace: "{{ vdasize }}"
- name: 6. vdbsize
replace:
path: "{{ sfile }}"
regexp: disk_vdb_size
replace: "{{ vdbsize }}"
...
```
3.執行hwreport.yml
```*=
[student@control ansible]$ ansible-playbook hwreport.yml
```
**4.檢查/root/hwreport.txt**
```*=
[student@control ansible]$ ansible all -m shell -a 'cat /root/hwreport.txt'
```
## Q14 建立密碼保險櫃
1.先建立密碼檔 secrec.txt
```*=
[student@control ansible]$ touch secret.txt
[student@control ansible]$ vim secret.txt
whenyouwishuponastar
```
2.ansible-vault建立locker.yml帶入密碼檔secret.txt
```*=
student@control ansible]$ ansible-vault create locker.yml --vault-id secret.txt
---
- pw_developer: Imadev
- pw_manager: Imamgr
```
**3.檢查密碼**
```*=
student@control ansible]$ ansible-vault view locker.yml --vault-id secret.txt
```
## Q15 建立使用者帳戶
1.wget 下載 user_list.yml
```*=
[student@control ansible]$ wget http://data.example.com/materials/user_list.yml
--2024-01-09 09:08:46-- http://data.example.com/materials/user_list.yml
Resolving data.example.com (data.example.com)... 172.24.1.254
Connecting to data.example.com (data.example.com)|172.24.1.254|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 107
Saving to: ‘user_list.yml’
user_list.yml 100%[===================>] 107 --.-KB/s in 0s
2024-01-09 09:08:46 (19.5 MB/s) - ‘user_list.yml’ saved [107/107]
```
2.編輯users.yml
```*=
[student@control ansible]$ touch users.yml
[student@control ansible]$ vim users.yml
---
- name: Q15. developer
hosts: dev,test
vars_files:
- locker.yml
- user_list.yml
tasks:
- name: 1.1 create group
group:
name: devops
state: present
- name: developer
user:
name: "{{ item.name }}"
password: "{{ pw_developer |password_hash('sha512') }}"
group: devops
state: present
loop: "{{ users }}"
when: item.job == "developer"
- name: Q15. manager
hosts: prod
vars_files:
- locker.yml
- user_list.yml
tasks:
- name: 1.1 create group
group:
name: opsmgr
state: present
- name: managerr
user:
name: "{{ item.name }}"
password: "{{ pw_manager |password_hash('sha512') }}"
group: opsmgr
state: present
loop: "{{ users }}"
when: item.job == "manager"
```
3.執行users.yml
```*=
[student@control ansible]$ ansible-playbook users.yml --vault-id secret.txt
```
**4.檢查建立的使用者**
```*=
[student@control ansible]$ ansible dev,test -m shell -a 'tail -n 5 /etc/passwd'
[student@control ansible]$ ansible prod -m shell -a 'tail -n 5 /etc/passwd'
```
## Q16 重新產生ANSIBLE保險櫃密鑰
1.wget http://data.example.com/materials/salaries.yml 下載要更改密碼的檔案
```*=
[student@control ansible]$ wget http://data.example.com/materials/salaries.yml
--2024-01-09 09:22:47-- http://data.example.com/materials/salaries.yml
Resolving data.example.com (data.example.com)... 172.24.1.254
Connecting to data.example.com (data.example.com)|172.24.1.254|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 808
Saving to: ‘salaries.yml’
salaries.yml 100%[===================>] 808 --.-KB/s in 0s
2024-01-09 09:22:47 (137 MB/s) - ‘salaries.yml’ saved [808/808]
```
2.ansible-vault rekey密碼
```*=
[student@control ansible]$ ansible-vault rekey salaries.yml
Vault password: 原本的密碼
New Vault password: 新密碼
Confirm New Vault password: 重新輸入一次新密碼
Rekey successful
```
**3.檢查密碼**
```*=
[student@control ansible]$ ansible-vault view salaries.yml
Vault password: 輸入更改後的密碼
```
## Q17 設定CRON工作
1.編輯cron.yml
```*=
[student@control ansible]$ touch cron.yml
[student@control ansible]$ vim cron.yml
---
- name: q17 cron
hosts: all
tasks:
- name: Create student
user:
name: student
state: present
- name: Create cron
cron:
name: logger "Hello World"
user: student
minute: "*/2"
job: 'logger "Hello World"
```
**2.檢查cron**
```*=
[student@control ansible]$ ansible all -m shell -a 'crontab -u student -l'
node5 | CHANGED | rc=0 >>
#Ansible: Hello World
*/2 * * * * logger "Hello World"
node1 | CHANGED | rc=0 >>
#Ansible: Hello World
*/2 * * * * logger "Hello World"
node4 | CHANGED | rc=0 >>
#Ansible: Hello World
*/2 * * * * logger "Hello World"
node2 | CHANGED | rc=0 >>
#Ansible: Hello World
*/2 * * * * logger "Hello World"
node3 | CHANGED | rc=0 >>
#Ansible: Hello World
*/2 * * * * logger "Hello World"
```