2015年11月11日 星期三

Ansible 筆記 - 透過 ansible 指令、ansible-playbook 執行批次腳本等用法快速上手 @ Ubuntu 14.04

剛接手一份用 Puppet 維護的服務,結果 Puppet 還沒玩熟,就先來改玩一下 Ansible,而 Ansible 也是一套機器部署的軟體,最大特色是不需要 master-slave(client) 架構,也就是被管理的機器不用安裝 ansible 啦!另外還有類似市集功能,例如你想要找 nginx 的設定方式,那只要上市集找一下,接著把它下載回來,套用一下,即可部署,十分便利。

首先先摸一下 ansible 指令,熟了再把玩 ansible-playbook 批次指令,之後再從 ansible-galaxy 從市集找設定檔。

安裝 ansible ( http://docs.ansible.com/ansible/intro_installation.html#id17 ):

$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
$ ansible --version
ansible 1.9.4


接著,來試試 ansible 指令吧!這個指令的用法就像執行 ssh remote commands 一樣:

$ ansible localhost -m raw -a "date"
localhost | success | rc=0 >>
Wed Nov 11 11:01:21 UTC 2015

$ ansible localhost -m setup
...用 JSON Format 列出系統資訊...

$ ansible localhost -m setup | grep -i ubuntu
        "ansible_distribution": "Ubuntu",
            "description": "Ubuntu 14.04.3 LTS",
            "id": "Ubuntu",


然而,localhost 是一個默認的字眼,若要對遠端機器操作時,必須先寫定 hosts 對應表,預設是使用 /etc/ansible/hosts 位置,但也可以透過 -i filename 來使用,這裡使用 -i 來試試,並用 127.0.0.1 為例。

$ cat hosts
[webserver]
127.0.0.1

$ ansible -i etc/ansible/hosts webservers --list-hosts
    127.0.0.1

$ ansible -i etc/ansible/hosts webservers -m raw -a "date"
127.0.0.1 | FAILED | rc=255 >>

$ ansible -i etc/ansible/hosts --private-key=~/.ssh/id_rsa webservers -m raw -a "date"
127.0.0.1 | success | rc=0 >>
Wed Nov 11 11:27:36 UTC 2015

$ ansible -i etc/ansible/hosts --private-key=~/.ssh/id_rsa webservers -m setup | grep -i cpu
            "Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz",
            "Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz"
        "ansible_processor_vcpus": 2,


其中 -m 代表要採用的模組,而 -a 是該模組的參數資訊。 raw 代表 -a 後頭的指令就給他執行下去就對了。所以一些常用的 ssh remote command 則是可以用 -m raw 來替代。其中 --private-key 是指定登入用的 key,而 -u 還可以指定登入的使用者。

接下來透過 yml 檔案描述來批次處理大量指令:

$ cat webserver.yml
---
- hosts: webserver
  tasks:
  - shell: date

$ ansible-playbook -i etc/ansible/hosts --private-key=~/.ssh/id_rsa webserver.yml
PLAY [webserver] **************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [shell date] ************************************************************
changed: [127.0.0.1]

PLAY RECAP ********************************************************************
127.0.0.1            : ok=2    changed=1    unreachable=0    failed=0


以上是非常簡單的批次任務,在複雜下去之前,先介紹一招透過 yml 檔案來新增 ssh remote key 方式(等同於 ssh-copy-id 功能):

$ cat add_authorized_key.yml
- hosts: '{{host}}'
  remote_user: '{{user}}'
  vars:
      ssh_private_key_path: '{{ ssh_key_file }}'

  tasks:
  - name: Add RSA key to the remote host
    authorized_key: user='{{user}}' key="{{lookup('file', ssh_private_key_path )}}"

$ ansible-playbook add_authorized_key.yml -i hosts

PLAY [{{host}}] ***************************************************************
skipping: no hosts matched

PLAY RECAP ********************************************************************

$ ansible-playbook add_authorized_key.yml -i hosts --ask-pass --extra-vars "user=ubuntu host=localhost ssh_key_file=ansible-deploy.pub"                                                                                                            
SSH password:

PLAY [localhost] **************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [Add RSA key to the remote host] ****************************************
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0


這個過程就是透過 add_authorized_key.yml 腳本,以及搭配的參數去執行,將 ansible-deploy.pub 檔案添加至 ubuntu@localhost 的 ~/.ssh/authorized_key 且確保此動作重複執行也不會添加重複筆數,在執行一次得到的結果:

$ ansible-playbook add_authorized_key.yml -i hosts --extra-vars "user=ubuntu host=localhost ssh_key_file=ansible-deploy.pub"                                                                                                            
SSH password:

PLAY [localhost] **************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [Add RSA key to the remote host] ****************************************
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0


可以清楚看到最後一個回報的 changed=0 ,代表此執行執行成功但沒有改變東西。且由於 key 已經添加,這次可以去掉 --ask-pass 的用法。這件事代表可以每次都重跑一樣的工作,但已經生效的不會再重做。

接著來寫個範本是每次執行都會把 EC2 系統更新至最新版(-u 代表要用 ubuntu 帳號登入,-s 則是用 sudo 執行):

$ cat update-ec2-ubuntu.yml
---
- hosts: ec2-servers
  tasks:
  - apt: upgrade=dist

$ ansible-playbook update-ec2-ubuntu.yml -i hosts --private-key=ansible-deploy.pem -u ubuntu -s
PLAY [ec2-servers] **************************************************

GATHERING FACTS ***************************************************************
ok: [XX.XX.XX.XX]

TASK: [apt upgrade=dist] ******************************************************

changed: [XX.XX.XX.XX]

PLAY RECAP ********************************************************************
XX.XX.XX.XX             : ok=2    changed=1    unreachable=0    failed=0


同理再跑一次,可以看到 changed=0,代表第二次已沒有需要更新的。

未來則就可以依照需求撰寫各台機器的部署腳本,其中還有更豐富的 roles 跟 ansible-galaxy 還沒把玩,晚點再來試試吧。

2 則留言:

  1. 最近也開始嘗試用 ansible 來取代一些 devops 的工作了,目前一切感覺良好啊 XD

    回覆刪除
    回覆
    1. 讚哦!我也才剛玩不到兩個月,預計把所有服務的發佈都轉換過去!

      刪除