# Ansible *橘圈表示機器, 灰框表示群組* ![photo_2024-06-14_13-01-32](https://hackmd.io/_uploads/H1KT0SFr0.jpg) **Ansible較適用於中小型的管理** **安裝在圖中的主機器上, 讓他去控制其他機器** **控制方式** 1. ad hoc (在command line 一行一行輸入) 2. script (寫一個ansible 的腳本一次執行多項指令) --- ## 先設定無密碼登入 **建議使用root的無密碼登入, 後續需要進行一些系統的操作才不須提權** https://hackmd.io/@LSX-0123/SkgsSOt8p 否則後續執行時都須輸入sudo 密碼 ![image](https://hackmd.io/_uploads/Bk0YVUKrA.png) ## 安裝及配置 改權限的東東 https://how64bit.com/posts/ansible/2022/ansible-configuration/ * 安裝軟體 `sudo yum install -y ansible` * 設定權限 (如果無密碼登入部分使用root 權限操作跳到下一項) 參考: [Ansible - 管理 Ansible 設定組態檔](https://how64bit.com/posts/ansible/2022/ansible-configuration/) 修改下面兩項 (defaults 和 privilege_escalation) `sudo vim /etc/ansible/ansible.cfg` ```bash= [defaults] inventory = /etc/ansible/hosts ask_pass = False [privilege_escalation] become=True become_method=sudo become_user=root become_password=user become_ask_pass=True ``` * 配置設定 `sudo vim /etc/ansible/hosts` **新增群組** ```bash= [server1] 192.168.68.157 [server2] 192.168.68.163 [servers] 192.168.68.157 192.168.68.163 ``` * ping 測試 ```bash= ansible server1 -m ping ansible servers -m ping ansible server2 -m ping ``` ![螢幕擷取畫面 2024-05-29 102206](https://hackmd.io/_uploads/S1brDfV4A.png) ## ansible 操作 * 加入ubuntu (server2) **修改 vim /etc/ssh/sshd_config** **PermitedRootLogin yes** ```bash= # 如果 "a" 不存在, 新增 "a" 如果 "a" 存在 跳過後面的命令 [user@d1 ~]$ ansible server1 -m command -a "creates=a touch a" [WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 192.168.68.157 | CHANGED | rc=0 >> [user@d1 ~]$ ansible server1 -m command -a "creates=a touch a" 192.168.68.157 | SUCCESS | rc=0 >> skipped, since a exists [user@d1 ~]$ ansible server1 -m command -a "ls" 192.168.68.157 | CHANGED | rc=0 >> a ``` * ad hoc * command ( 較複雜的混合指令無法用它 ) `$ ansible server1 -m command -a "ifconfig"` ![image](https://hackmd.io/_uploads/BkDwKUKB0.png) * 腳本 ```bash= [user@d1 Desktop]$ cat test.sh whoami hostname ``` ```bash= [user@d1 Desktop]$ ansible all -m script -a "./test.sh" 192.168.68.154 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.68.154 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.68.154 closed." ], "stdout": "user\r\nvm\r\n", "stdout_lines": [ "user", # response "vm" # response ] } 192.168.68.157 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.68.157 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.68.157 closed." ], "stdout": "user\r\nd2\r\n", "stdout_lines": [ "user", # response "d2" # response ] } ``` * 安裝 刪除 ```bash= [user@d1 Desktop]$ ansible server3 -m apt -a "name=tree state=absent" BECOME password: 192.168.68.154 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "stderr": "", "stderr_lines": [], "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nThe following packages were automatically installed and are no longer required:\n cpu-checker ibverbs-providers ipxe-qemu ipxe-qemu-256k-compat-efi-roms\n libaio1 libcacard0 libdaxctl1 libdecor-0-0 libdecor-0-plugin-1-cairo libfdt1\n libgfapi0 libgfrpc0 libgfxdr0 libglusterfs0 libibverbs1 libiscsi7 libndctl6\n libpmem1 libpmemobj1 libqrencode4 librados2 librbd1 librdmacm1 libsdl2-2.0-0\n libspice-server1 liburing2 libusbredirparser1 libvirglrenderer1 msr-tools\n ovmf qemu-block-extra qemu-system-common qemu-system-data qemu-system-gui\n qemu-system-x86 qemu-utils qrencode seabios uidmap xclip\nUse 'sudo apt autoremove' to remove them.\nThe following packages will be REMOVED:\n pass tree\n0 upgraded, 0 newly installed, 2 to remove and 211 not upgraded.\nAfter this operation, 249 kB disk space will be freed.\n(Reading database ... \r(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r(Reading database ... 70%\r(Reading database ... 75%\r(Reading database ... 80%\r(Reading database ... 85%\r(Reading database ... 90%\r(Reading database ... 95%\r(Reading database ... 100%\r(Reading database ... 224892 files and directories currently installed.)\r\nRemoving pass (1.7.4-5) ...\r\nRemoving tree (2.0.2-1) ...\r\nProcessing triggers for man-db (2.10.2-1) ...\r\n", "stdout_lines": [ "Reading package lists...", "Building dependency tree...", . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "(Reading database ... 224892 files and directories currently installed.)", "Removing pass (1.7.4-5) ...", "Removing tree (2.0.2-1) ...", "Processing triggers for man-db (2.10.2-1) ..." ] } [user@d1 Desktop]$ ansible server3 -m apt -a "name=tree state=present" BECOME password: 192.168.68.154 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "cache_update_time": 1717550543, "cache_updated": false, "changed": true, "stderr": "", . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "(Reading database ... 224855 files and directories currently installed.)", "Preparing to unpack .../tree_2.0.2-1_amd64.deb ...", "Unpacking tree (2.0.2-1) ...", "Setting up tree (2.0.2-1) ...", "Processing triggers for man-db (2.10.2-1) ..." ] } ``` * 複製資料 ( copy ) ```bash= $ echo "hello" > hello.txt [user@d1 ansible]$ ansible server1 -m copy -a "src=./hello.txt dest=/tmp/hello.txt owner=user group=user mode=0644" 192.168.68.157 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "f572d396fae9206628714fb2ce00f72e94f2258f", "dest": "/tmp/hello.txt", "gid": 1000, "group": "user", "md5sum": "b1946ac92492d2347c6235b4d2611184", "mode": "0644", "owner": "user", "size": 6, "src": "/home/user/.ansible/tmp/ansible-tmp-1718346500.52-6651-92054779023352/source", "state": "file", "uid": 1000 } [user@d1 ansible]$ ansible server1 -m command -a "ls -l /tmp/hello.txt" 192.168.68.157 | CHANGED | rc=0 >> -rw-r--r-- 1 user user 6 Jun 13 23:28 /tmp/hello.txt ``` * 改變屬性 ( file ) ```bash= [user@d1 ansible]$ ansible server1 -m file -a "path=/tmp/hello.txt owner=root group=root mode=0755" 192.168.68.157 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/hello.txt", "size": 6, "state": "file", "uid": 0 } [user@d1 ansible]$ ansible server1 -m command -a "ls -l /tmp/hello.txt" 192.168.68.157 | CHANGED | rc=0 >> -rwxr-xr-x 1 root root 6 Jun 13 23:28 /tmp/hello.txt ``` * 腳本使用 (playbook) * ping ```yaml= --- - hosts: server1 tasks: - name: test ping ping: ``` **結果** ![image](https://hackmd.io/_uploads/ryUEO8tS0.png) * 新增檔案 ```taml= --- - hosts: server1 gather_facts: no tasks: - name: create an empty file under /tmp command: chdir: /tmp cmd: touch a.txt - name: list all files under /tmp and grep shell: chdir: /tmp cmd: "ls -l | grep a.txt" register: results - name: show the results debug: msg: "{{ results['stdout'] }}" ``` ![photo_2024-06-14_13-54-44](https://hackmd.io/_uploads/B1OUiUFrC.jpg) * 套用變數 ( JinJa2 ) **test3.yml** ```yaml= --- - hosts: server1 gather_facts: no vars: dynamic_world: "World" tasks: - name: test template template: src: hi.j2 dest: /tmp/hello_world.txt ``` **hi.j2** ```jinja2= hello "{{ dynamic_world }}" ``` **run** ```bash= $ ansible-playbook test3.yml $ ansible server1 -m command -a "cat /tmp/hello_world.txt" 192.168.68.157 | CHANGED | rc=0 >> hello "World" ``` * 指定作業系統 **test4.yml** ```yaml= --- - hosts: servers gather_facts: yes tasks: - name: test ping ping: - name: install software packages in CentOS yum: name: - vim - curl state: present when: ansible_facts['distribution'] == "CentOS" ``` ![image](https://hackmd.io/_uploads/HkLCdvFBA.png) * 改變網頁伺服器的port **複製配置檔** `$ cp /etc/httpd/conf/httpd.conf ./httpd.conf.j2` **把裡面port 的位置改成j2 的變數格式** ![image](https://hackmd.io/_uploads/S1q89vFr0.png) **簡單網頁** ```bash= $ cat hi.htm hi ``` **test5.yml** ```yaml= --- - hosts: server1 gather_facts: no vars: listen_port: 8080 tasks: - name: install httpd yum: name: - httpd state: present - name: copy conf file template: src: httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf - name: htm copy: src: ./hi.htm dest: /var/www/html/hi.htm - name: restart httpd server service: name: httpd state: restarted ``` **結果** ![image](https://hackmd.io/_uploads/BJfE2DYBC.png) ```bash= $ curl http://d2:8080/hi.htm hi ```