星期日, 11月 15, 2015

Ansible 小記 - 用 playbook 安裝 nginx

上次介紹 playbook
接下來要在沒有很了解 playbook 以及 module 的情況下, 來實驗書上的第一個 playbook - nginx 安裝.

接下來的筆記就會規劃 不同 module 的指令還有 playbook 的實作

Lab: 安裝 nginx without TLS

在 playbook 目錄下
$ vi   web-notls.yml
- name: Configure webserver with nginx
 hosts: webservers
 sudo: True
 tasks:
   - name: install nginx
     apt: name=nginx update_cache=yes

   - name: copy nginx config file
     copy: src=files/nginx.conf  dest=/etc/nginx/sites-available/default

   - name: enable configuration
     file: >
       dest=/etc/nginx/sites-enabled/default
       src=/etc/nginx/sites-available/default
       state=link

   - name: copy index.html
     template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html
       mode=0644

   - name: restart nginx
     service: name=nginx state=restarted


建立 預設的 conf 檔案( 對應上方的設定 )
在 playbook 目錄下
$ mkdir  files

建立設定檔
$ vi  files/nginx.conf
server {
       listen 80 default_server;
       listen [::]:80 default_server ipv6only=on;

       root /usr/share/nginx/html;
       index index.html index.htm;

       server_name localhost;

       location / {
                try_files $uri $uri/ =404;
       }
}

建立 templates 目錄
在 playbook 目錄下
$ mkdir  templates

建立首頁的範本
$ vi   templates/index.html.j2
<html>
<head>
   <title>Welcome to ansible</title>
</head>
<body>
<h1>nginx, configured by Ansible</h1>
<p>If you can see this, Ansible successfully installed nginx.</p>

<p>{{ ansible_managed }}</p>
</body>
</html>

修改 hosts 檔案( 因為上面的 web-notls.yml 對象是 webservers 群組  )
在 playbook 目錄下
新增 webservers 群組
$ vi  hosts
ubuntu_utah ansible_ssh_host=pcvm2-13.utah.geniracks.net

ubuntu_cenic ansible_ssh_host=pcvm2-28.instageni.cenic.net

[geni]
ubuntu_utah
ubuntu_cenic

[webservers]
ubuntu_utah

測試群組
$ ansible   webservers   -m ping
ubuntu_utah | success >> {
   "changed": false,
   "ping": "pong"
}



觀察目前目錄下物件
$ ls -R
ansible.cfg   files         hosts         templates     web-notls.yml

./files:
nginx.conf

./templates:
index.html.j2

執行  playbook

$ ansible-playbook   web-notls.yml

驗證 webservers 主機的 port 80

成功之後來進行另外一個 Lab

Lab: 使用 TLS support 的 nginx

在 playbooks 目錄下
$ vi   web-tls.yml

- name: Configure webserver with nginx and tls
 hosts: webservers
 sudo: True
 vars:
   key_file: /etc/nginx/ssl/nginx.key
   cert_file: /etc/nginx/ssl/nginx.crt
   conf_file: /etc/nginx/sites-available/default
   server_name: localhost
 tasks:
   - name: Install nginx
     apt: name=nginx update_cache=yes cache_valid_time=3600

   - name: create directories for ssl certificates
     file: path=/etc/nginx/ssl state=directory

   - name: copy TLS key
     copy: src=files/nginx.key dest={{ key_file }} owner=root mode=0600
     notify: restart nginx

   - name: copy TLS certificate
     copy: src=files/nginx.crt dest={{ cert_file }}
     notify: restart nginx

   - name: copy nginx config file
     template: src=templates/nginx.conf.j2 dest={{ conf_file }}
     notify: restart nginx

   - name: enable configuration
     file: dest=/etc/nginx/sites-enabled/default src={{ conf_file }} state=link
     notify: restart nginx

   - name: copy index.html
     template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html mode=0644

 handlers:
   - name: restart nginx
     service: name=nginx state=restarted

手動建立憑證
在 playbooks 目錄下
使用 openssl 指令建立憑證
$ openssl  req  -x509  -nodes  -days 3650 -newkey rsa:2048 -subj /CN=localhost -keyout files/nginx.key -out files/nginx.crt
Generating a 2048 bit RSA private key
........................................+++
...............................................+++
writing new private key to 'files/nginx.key'
-----

驗證輸出
$ ls   files/
nginx.conf nginx.crt  nginx.key

建立 nginx.conf.j2  給支援 tls 設定檔使用 ( 跟沒有 TLS 的差異為紅色部分 )

在 playbooks 目錄下

$ vi  templatess/nginx.conf.j2

server {
       listen 80 default_server;
       listen [::]:80 default_server ipv6only=on;

       listen 443 ssl;

       root /usr/share/nginx/html;
       index index.html index.htm;

       server_name {{ server_name }};
       ssl_certificate {{ cert_file }};
       ssl_certificate_key {{ key_file }};

       location / {
                try_files $uri $uri/ =404;
       }
}

使用之前已經安裝過的主機測試  playbook
$ ansible-playbook   web-tls.yml
PLAY [Configure webserver with nginx and tls] *********************************

GATHERING FACTS ***************************************************************
ok: [ubuntu_utah]

TASK: [Install nginx] *********************************************************
ok: [ubuntu_utah]

TASK: [create directories for ssl certificates] *******************************
ok: [ubuntu_utah]

TASK: [copy TLS key] **********************************************************
ok: [ubuntu_utah]

TASK: [copy TLS certificate] **************************************************
ok: [ubuntu_utah]

TASK: [copy nginx config file] ************************************************
changed: [ubuntu_utah]

TASK: [enable configuration] **************************************************
ok: [ubuntu_utah]

TASK: [copy index.html] *******************************************************
changed: [ubuntu_utah]

NOTIFIED: [restart nginx] *****************************************************
changed: [ubuntu_utah]

PLAY RECAP ********************************************************************
ubuntu_utah                : ok=9    changed=3    unreachable=0    failed=0

測試完全新的 ubuntu_cenic 也okay

今天先到這邊

~ enjoy it



星期六, 10月 31, 2015

Ansible playbook小記

上一次寫完 Ansible 簡單的指令測試
今天來介紹 playbook

playbook  簡單來說就是
  • 把要執行的 ansible 指令還有可能遠端主機會使用到的檔案都集中到一個目錄內.
  • 以YAML 語法來寫
  • ansible-playbook 指令執行
  • playbook 裡面會有不同的 play ( 可以把看成要執行的script )
    • 每個 play 必須有
      • 要執行的 host ( 對應我們設定的 hosts 或是 inventory 檔案 )
      • task ( 執行那些工作)

以下是看書上,自己的整理筆記

playbook
  • A script is called a playbook.
  • A playbook describes which hosts( what Ansible calls remote servers ) to configure, and an ordered list of tasks to perform on those hosts.
    • Ansible runs each task in parallel across all hosts.
    • Ansible waits until all hosts have completed a task before moving to the next task.
    • Ansible runs the tasks in the order that you specify them.
  • 使用 ansible-playbook 指令來執行
    • # 例如 ansible-playbook  web-notls.yml
    • 如果檔案本身可以被執行
    • 也可以在檔案第一行加上
    • #!/usr/bin/env  ansible-playbook
    • 來直接執行
  • Ansible playbooks written in YAML syntax.
    • YAML
    • Yet Another Markup Language
      • Start of File
        • 以 3 個 --- 開始
        • 不加上去也可以
      • 註解
        • 以 # 來進行單行註解
        • #就是註解開始
      • Strings
        • 不一定要加上引號
        • 可是有的時候為了易讀性, 可以使用 單引號或是雙引號
      • Booleans
        • 使用 True 或是 Yes 都可以視為真
        • 但是還是用 True 不會混亂
      • Lists
They are delimited with hyphens, like this:
- My Fair Lady
- Oklahoma
- The pirates of Penzance
# inline 格式list
[My Fair Lady, Oklahoma, The Pirates of Penzance]
      • Dictionaries
They look like this:
address: 742 Evergreen Terrace
city: Springfield
state: North Takoma
# inline  格式
{address: 742 Evergreen Terrace, city: Springfield, state: North Takoma}
      • Line Folding
# 使用 > 符號來進行 單行摺疊, 有點類似 shell script 放在行尾的 \
# 目的在於讓一個很長的單行, 有效率地被呈現
address: >
     Department of Computer Science,
     A.V. Williams Building,
     University of Maryland
city: College Park
state: Maryland
# address 那邊就可以看成一行
  • A playbook is a list of plays
    • Plays
      • Every play must contain:
        • * A set of hosts to configure
        • * A list of tasks to be executed on those hosts
      • Three common optional settings are
        • name
          • A comment that describes what the play is about.
          • Ansible will print this out when the play starts to run.
        • sudo
          • If true, Ansible will run every task by sudo.
        • vars
          • A list of variables and values.
          • 在 play 內用  {{  }} 來使用 variables
      • Other optional settings are
        • Handlers
A handler is similar to a task, but it runs only if it has been notified by a task.
A task will fire the notification if Ansible recognizes that the task has changed the state of the system.
# 當 task 改變系統狀態時, 會進行 notify 的動作
tasks:
 - name: copy TLS key
    copy: src=files/nginx.key dest={{ key_file }} owner=root mode=0600
    notify: restart nginx
# handlers 可能有很多個, notify 會去比對 handlers 的名稱, 如果符合就進行該模組
handlers:
- name: restart nginx
  service: name=nginx state=restarted
# 也就是說, 只有真的系統產生改變的時候, 例如 TLS key 被換掉, 才會重新啟動 nginx
          • Handlers only run after all of the tasks are run, and the only run once, even they are notified multiple times.
          • # Handlers 在所有tasks執行完才執行, 不管被呼叫多少次, 都只執行一次.
      • hosts
        • default: /etc/ansible/hosts
      • Tasks