:::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" ```