#author("2019-10-16T17:13:50+00:00","default:sysosa","sysosa")
#author("2022-09-06T23:31:54+00:00","default:sysosa","sysosa")
[[kickstart]]で大本は作れたが、細かい箇所もサーバ構築の自動化するのに使ってみた
&size(10){はじめChefを使ったが分かりにくかったのでこちらへ転向した};

[[Ansible/Playbook]]


***インストール [#q58b4a08]
作業するマシンにインストールします。作業対象にインストールする必要はありません。
ここでは管理サーバ c.sybyl.local にAnsibleをインストールします
パッケージは epel リポジトリに存在しているので

#code(nonumber){{
[root@c ~]# yum install epel-release
[root@c ~]# yum install --enablerepo=epel install ansible
}}

これで完了みたい

***管理対象の登録 [#m1b4a6ae]
ansibleのインストールが完了すると /etc/ansible が作られる。
そこに &color(magenta){hosts};ファイルが存在する。ここに管理対象のホストを記載します

#code(nonumber){{
[root@c ~]# ls -l /etc/ansible/
合計 24
-rw-r--r-- 1 root root 18066  6月  2 06:49 ansible.cfg
-rw-r--r-- 1 root root  1016  6月  2 06:49 hosts
drwxr-xr-x 2 root root     6  6月  2 06:49 roles
[root@c ~]#
}}

&color(magenta){hosts};ファイルには記載例が書かれており、単純に対象を個別に登録するほか、グループを作ったりホスト名の連番とかにも対応するみたい. ホスト名でもIPアドレスでも可

ここではグループ名 &color(orangered){cluster}; を作り、その中に連番のホスト( n[1:4].sybyl.local )とを持たせてみた
#code(nonumber){{
[root@c ~]# cat /etc/ansible/hosts
[cluster]
n[1:4].sybyl.local
                      <--  グループとの区切りは空行
nfs.sybyl.local       <--  単発指定
[root@c ~]#
}}
このファイルは各自のユーザにて用意して、「」

***ssh接続 [#i39de3f4]
ansibleはsshで相手方(管理対象)に接続して操作を行う
基本「パスワード」入力無しで接続を前提にしているようで、相手方(illya@nfs.sybyl.local)へはパスワードが必要な状態だと
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m ping
nfs.sybyl.local | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n",
    "unreachable": true
}
[illya@c ~]$
}}
と言われる. この場合は「--ask-pass」を入れて、パスワード入力を有効にする必要がある.
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m ping  --ask-pass
SSH password:                     <-- ここで相手方(illya@nfs.sybyl.local)のパスワードを入力する
nfs.sybyl.local | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[illya@c ~]$
}}
相手側が自分ではない他のユーザ(root@nfs.sybyl.local)として接続したいのなら、「--user」で指定する
&size(10){ 「[illya@c ~]$ ssh -l root nfs.sybyl.local」な感じで、nfsにrootで接続して、--ask-passでパスワードを入力な感じ。};
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m ping  --ask-pass  --user root
SSH password:                     <-- ここで相手方(root@nfs.sybyl.local)のパスワードを入力する
nfs.sybyl.local | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[illya@c ~]$
}}


もし自分の公開鍵が相手側の .ssh/authorized_keys に登録されていれば パスフレーズ が自動的に求められる.
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m ping
Enter passphrase for key '/home/illya/.ssh/id_rsa':    <-- ここにパスフレーズを入力
nfs.sybyl.local | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[illya@c ~]$
}}
さらに鍵の作成時に パスフレーズ を指定しない場合だと、当然ながらパスフレーズを問わず実行できます
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m ping
nfs.sybyl.local | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[illya@c ~]$
}}
自分の(パスフレーズなしな)公開鍵を相手側の root の .ssh/authorized_keys に入っているなら
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m ping --user root
nfs.sybyl.local | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[illya@c ~]$
}}
ssh-agentを使っても構わない [[ssh/ssh-agent]]
&color(red){*};&size(10){[[ホストベース認証>ssh/ホストベース認証]]も有効でした};


凝った方法.「-k(--ask-pass)」と「--user ABC」で相手先にユーザABCでログインして、
その後に「-b(--become)」で別ユーザになってコマンドを実行させる. 
その際「--become-method=su」と「su」で「--become-user root」とユーザ「root」になるために「-K(--ask-become-pass)」でパスワード入力をさせる

#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m ping -k         -u illya     -b       --become-method=su -K
            (ansible nfs.sybyl.local -m ping --ask-pass --user illya --become --become-method=su --ask-become-pass)

SSH password:                                      <-- 「-k」で要求される「--user」のパスワード (illya@nfs.sybyl.local)
BECOME password[defaults to SSH password]:         <-- 「-K」で要求される「--become-user」のパスワード(root@nfs.sybyl.local)
nfs.sybyl.local | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[illya@c ~]$
}}


***root権限操作 [#cbe88943]
一般ユーザで相手側にログインするので、当然その権限はそのユーザの範囲内に制限される.
相手方に/dataディレクトリを作る場合
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m file -a "path=/data state=directory mode=0755" --ask-pass
SSH password:
nfs.sybyl.local | FAILED! => {
    "changed": false,
    "failed": true,
    "msg": "There was an issue creating /data as requested: [Errno 13] 許可がありません: '/data'",
    "path": "/data",
    "state": "absent"
}
[illya@c ~]$
}}
と当然ながら拒否される。
リモートから直接rootになれる環境なら単に「--user root」でもいいのだが、
sshdの設定で「&color(magenta){PermitRootLogin no};」とあった場合、自分のアカウントとかで相手先(illya@nfs.sybyl.local)に接続して
その後 su して root(root@nfs.sybyl.local) に switch する必要がある。

下記は、
「--ask-pass」で相手先(illya@nfs.sybyl.local)のパスワード入力を行い
「--su」で相手マシン(nfs.sybyl.local)で「su」を行い
「--su-user root」で「su」の対象はroot(root@nfs.sybyl.local)で
「--ask-su-pass」で「su」の際のパスワード入力を行う
&size(10){「--su-user=」は既定でrootですが、明示的に指定しました};
#code(nonumber){{
[illya@c ~]$ ansible nfs.sybyl.local -m file -a "path=/data state=directory mode=0755" --ask-pass --su --su-user=root --ask-su-pass
SSH password:                                <-- 相手方へのログインパスワード
SU password[defaults to SSH password]:       <-- 相手方でrootになるためのパスワード
nfs.sybyl.local | SUCCESS => {
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/data",
    "size": 6,
    "state": "directory",
    "uid": 0
}
[illya@c ~]$
}}
相手方への接続は パスフレーズ なしの接続、ホストベース認証、kerberos認証らでパスワード無しができる。
&size(10){ssh-agentを使う方法もあるけど};
そして、相手方でroot権限で作業する際には「--su」より「--sudo」とsudoを用いる事でパスワード無しにも出来る
sudoでパスワード無しでroot権限が使えるようになるには [[visudo]] で /etc/sudoers の修正が必要です(相手側の/etc/sudoers).


***モジュール [#t66c05cb]
ansibleにて使用できるコマンドは[[http://docs.ansible.com/ansible/latest/modules_by_category.html>+http://docs.ansible.com/ansible/latest/modules_by_category.html]]に記載されている。
ここでは「System Modules」に存在するpingで死活監視、「Files Modules」に存在するfileにてディレクトリを作ってみた.

モジュールを見てみると、windowsマシンへの対応もあるようです


***Playbook [#i2796f47]
これら一番大事な箇所かも.
ansibleでの操作をファイルに記述して、それを実行する。そうすればそのマシンに対する作業履歴として残せる.
yum updateさせるファイル
#code(nonumber){{
[illya@c ~]$ cat yumupdate.yml
- hosts:  nfs.sybyl.local
  tasks:
  - name: yum update
    yum: name=*  state=latest
[illya@c ~]$
}}
そして、このファイルの文法チェックを行って
#code(nonumber){{
[illya@c ~]$ ansible-playbook yumupdate.yml --syntax-check

playbook: yumupdate.yml
[illya@c ~]$
}}
実際に実行します

#code(nonumber){{
[illya@c ~]$ ansible-playbook yumupdate.yml --ask-pass --su --su-user=root --ask-su-pass
SSH password:
SU password[defaults to SSH password]:

PLAY [nfs.sybyl.local] **************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************
ok: [nfs.sybyl.local]

TASK [yum update] *******************************************************************************************************
changed: [nfs.sybyl.local]

PLAY RECAP **************************************************************************************************************
nfs.sybyl.local            : ok=2    changed=1    unreachable=0    failed=0

[illya@c ~]
}}

yumupdate.ymlファイルの「hosts:」をグループ名とか「all」とかすれば、漏れなくyum updateができる。
っと言ってもこれはごくごく簡単な例。
実際にはcentos6とcentos7を区別して起動させるchkconfig/systemctlらを有効にして、実行とか
新たなマウントポイントのための/etc/fstabの書き換えとmountコマンドの実行とかがメインになるのかも


***Playbook(再起動) [#g0c701ca]
登録マシンを一斉に再起動させたいなら
#code(nonumber){{
- hosts:  e
  tasks:
  - name: reboot
    shell: "sleep 5 && reboot"
    async: 1
    poll: 0
    ignore_errors: true

  - name: wait
    wait_for_connection:
        connect_timeout: 20
        sleep: 5
        delay: 5
        timeout: 120

  - name: ping
    ping:
}}
とした reboot.yml を作って
#code(nonumber){{
[illya@c ~]$ ansible-playbook e.yml --user root --ask-pass
}}
と実行する。

***Playbook(一斉停止) [#q8fcd768]
&color(red){*};pukiwikiの表記規則から、「{{」を「{ }」に。「}}」を「} }」にしています。
#code(nonumber){{
- hosts: em
  tasks:
    - name: shutdown
      command: "/sbin/shutdown -h 1"

    - name: wait go down
      wait_for:
        host: "{ { inventory_hostname } }"
        port: 22
        state: stopped
      delegate_to: 127.0.0.1
}}
#code(nonumber){{
ansible-playbook shutdown.yml --user root --ask-pass
}}


***/etc/ansible/hostsに登録されていないマシンへの適用は? [#h895d160]
どうやらできるみたい
例えば、ad.sybyl.localに対して、environment-modulesを入れたいとして、
#code(nonumber){{
- hosts:  all
  tasks:
  - yum:  name=environment-modules state=latest
  - name: stat modulespath
    stat: path=/usr/share/Modules/init/.modulespath
    register: modulespath_stat

  - name: back up
    command: mv /usr/share/Modules/init/.modulespath /usr/share/Modules/init/.modulespath.orig
    when: modulespath_stat.stat.exists

  - name: modulespath.orig
    copy:
     dest: /usr/share/Modules/init/.modulespath
     content: |
         /home/Common/modules
}}
を用意したら
#code(nonumber){{
ansible-playbook -i ad, --user root ./EnvironmentModules.yml
}}
で成功した。要は「ad,」みたい。
&color(red){*};「- hosts: all」が前提みたい
1

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS