ansible初級メモ : Macにインストールからrbenv,nfsまで

メモ程度に投稿したblog記事のまとめです。
[ansible | okisanjp@ログってなんぼ](http://okisanjp.com/archives/tag/ansible "ansible | okisanjp@ログってなんぼ")

そもそも手探りで触っているので色々おかしいかもしれませんがツッコミくれれば検証後、修正したほうが良い内容なら修正します。

# インストール〜軽く何かインストール編

CentOS6のサーバーに対して、ローカルのmacからansibleを使って見たメモ

## macにansibleをインストールする

<a href="http://brew.sh/index_ja.html" target="_blank" class="linkurl">Homebrew</a>&nbsp;<a href="http://b.hatena.ne.jp/entry/http://brew.sh/index_ja.html" target="_blank"><img src="http://b.hatena.ne.jp/entry/image/http://brew.sh/index_ja.html" alt="はてなブックマーク - Homebrew — OS X 用パッケージマネージャー" title="はてなブックマーク - Homebrew — OS X 用パッケージマネージャー"></a> なら簡単にインストール可能

```
$ brew install ansible
```

### インベントリを作る

デフォルトでは hosts というファイルを探す。ansible.cfgで上書き変更可能

```
[test]
192.168.xxx.xxx
```

ローカルマシンからグローバルIPで操作したい場合にはグローバルIPを入れることもできる

FQDNも登録可能。その他 web[01-10]などといった指定や、正規表現も使用可能らしいがまだちゃんと理解していないのでとりあえず後回し。

### コマンドを実行してみる

管理対象サーバーで任意のコマンドを実行

```
$ ansible test -i hosts -a 'date'

192.168.xxx.xxx | SUCCESS | rc=0 >>
2016年  4月  8日 金曜日 14:27:27 JST
```

-mで実行するモジュールを指定、-aで引数を指定という流儀だと思うがサーバー上でのコマンド実行モジュールが -mのデフォルトのため、-aつまり実行したいワンライナーのみを指定すれば良いというふうに理解した（今のところ）モジュールについてはもっと理解を深める必要があるなと思っているところ

```
$ ansible test -i hosts -a 'cat /etc/redhat-release'
192.168.xxx.xxx | SUCCESS | rc=0 >>
CentOS release 6.7 (Final)
```

### Playbookを作る

#### 対象サーバーのコマンドラインにて

```
$ htop
-bash: htop: コマンドが見つかりません
```
と、いうわけでhtopが入っていないサーバーにhtopをインストールするPlaybookを書いてみる

#### yum-repos.yml

まずhtopのインストール元のyumリポジトリ(EPEL)を登録

```
- name: add repos 'EPEL'
  yum: name=http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm state=present
```

#### monitor-tools.yml

```
---
- hosts: test
  become: yes
  tasks:
    - name: Install htop
      yum: name=htop state=installed
```




#### 文法チェック

```
$ ansible-playbook -i hosts yum-repos.yml --syntax-check

playbook: yum-repos.yml
```

#### task内容チェック

```
$ ansible-playbook -i hosts yum-repos.yml --list-tasks

playbook: yum-repos.yml

  play #1 (test): 	TAGS: []
    tasks:
      add repos 'EPEL'	TAGS: []
```

#### dry-run

```
$ ansible-playbook -i hosts yum-repos.yml --check

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.xxx.xxx]

TASK [add repos 'EPEL'] ********************************************************
changed: [192.168.xxx.xxx]

PLAY RECAP *********************************************************************
192.168.xxx.xxx            : ok=2    changed=1    unreachable=0    failed=0
```

今回の場合、Playbookが複数あるので、各Playbookについてチェックしておく。ファイル名は、ワイルドカードで複数同時にチェックすることもできる

### Playbookを実行

まずリポジトリ

```
$ ansible-playbook -i hosts yum-repos.yml

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.xxx.xxx]

TASK [add repos 'EPEL'] ********************************************************
changed: [192.168.xxx.xxx]

PLAY RECAP *********************************************************************
192.168.xxx.xxx            : ok=2    changed=1    unreachable=0    failed=0
```

次にmonitor-tools

```
$ ansible-playbook -i hosts monitor-tools.yml

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.xxx.xxx]

TASK [Install htop] ***********************************************
changed: [192.168.xxx.xxx]

PLAY RECAP *********************************************************************
192.168.xxx.xxx            : ok=2    changed=1    unreachable=0    failed=0
```

ちなみに -i hostsはインベントリ（サーバー一覧）のファイル名を指定している部分なので、デフォルトのhostsで作成しているか、ansible.cfgで任意のファイルを指定してそのファイルが実在する場合、省略可能

## 確認

実際に管理対象のサーバーにログインしてみてhtopが有るか確認する

```
$ htop
```

ちゃんとインストールされていれば大成功。

# sudo出来るユーザー作成＆authorized_keys更新編

#### 参照
* [Ansibleでユーザを追加 - Qiita](http://qiita.com/kiarina/items/813878489f4adba4eb34 "Ansibleでユーザを追加 - Qiita")
* [ansible でノーパスログイン(公開鍵認証)設定する - とあるSIerの憂鬱](http://d.hatena.ne.jp/incarose86/20150215/1423992783 "ansible でノーパスログイン(公開鍵認証)設定する - とあるSIerの憂鬱")


```
- hosts: all
  become: True
  tasks:
    - name: add a new user
      user: name=hogeuser state=present
    - name: add a sudo user
      lineinfile: "dest=/etc/sudoers backup=yes state=present regexp='^hogeuser' line='hogeuser ALL=(ALL) NOPASSWD: ALL'"

- hosts: all
  tasks:
    - name: setup authorized_keys
      authorized_key: user=hogeuser
        key="{{ lookup('file', './id_rsa_hogeuser.pub') }}"
```

# rootユーザーでのログインを禁止編

notifyとhandlerを使ってサービスを再起動

```
- hosts: all
  become: True
  tasks:
    - name: stop root login via ssh
      lineinfile:
        dest: /etc/ssh/sshd_config
        state: present
        regexp: "^PermitRootLogin without-password"
        line: "PermitRootLogin no"
        backup: yes
        backrefs: yes
        validate: "sshd -T -f %s"
      notify: restart sshd

  handlers:
    - name: restart sshd
      service: name=sshd state=restarted
```

notifyに記入した名称と同じ名称でhandlerを設定しておくと、最後に処理を実行してくれる

同じnotifyが何度出てきても、最後に一度だけ実行される

1. ansibleの設定ファイルであるansible.cfgの置き場所には優先順位がある

1. 環境変数 ANSIBLE_CONFIG にて指定されたパス

1. カレントディレクトリの ansible.cfg (./ansible.cfg)

1. ユーザーHOMEの .ansible.cfg (~/.ansible.cfg)

1. /etc/ansible/ansible.cfg

# rbenv+rubyインストール編
appロールを作り、rbenvとrubyをインストールして使用できるようにするメモ

## hosts
```
[app]
app01 ansible_host=xxx.xxx.xxx.xxx
```

## app.yml

```
---
  - hosts: app 
    roles:
      - app
```

## roles/app/tasks/main.yml

```
---
  - name: 開発ツールをインストール
    become: True
    yum: name={{ item }} state=latest
    with_items:
      - git
      - openssl-devel
      - readline-devel
      - "@Development tools"

  - name: rbenvをインストール
    git: repo=https://github.com/sstephenson/rbenv.git dest=~/.rbenv

  - name: .bash_profileにパスを追加
    lineinfile: >
      dest="~/.bash_profile"
      line="export PATH=$HOME/.rbenv/bin:$PATH"

  - name: .bash_prifileにrbenv initを追加
    lineinfile: >
      dest="~/.bash_profile"
      line='eval "$(rbenv init -)"'

  - name: rbenv-buildのインストール
    git: repo=https://github.com/sstephenson/ruby-build.git dest=~/.rbenv/plugins/ruby-build
    
  - name: rubyのインストール
    shell: bash -lc "CONFIGURE_OPTS="--disable-install-rdoc" rbenv install -s {{ ruby_version }}"

  - name: globalで使用するバージョンを指定
    shell: bash -lc "rbenv global {{ ruby_version }} && rbenv rehash"
```

## roles/app/defaults/main.yml

tasksのmain.ymlで変数を使っているので、こちらに定義しておく。

```
---
  ruby_version: 2.1.8
```

## 実行してみる

```
$ ansible-playbook app.yml

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [app01]

TASK [app : 開発ツールをインストール] ******************************************************
changed: [app01] => (item=[u'git', u'openssl-devel', u'readline-devel', u'@Development tools'])

TASK [app : Install htop] ******************************************************
ok: [app01]

TASK [app : rbenvをインストール] ******************************************************
ok: [app01]

TASK [app : .bash_profileにパスを追加] ***********************************************
ok: [app01]

TASK [app : .bash_prifileにrbenv initを追加] ***************************************
ok: [app01]

TASK [app : rbenv-buildのインストール] ************************************************
ok: [app01]

TASK [app : rubyのインストール] *******************************************************
changed: [app01]

TASK [app : globalで使用するバージョンを指定] ***********************************************
changed: [app01]
```

### 実行前のチェック

#### 文法チェック

```
$ ansible-playbook app.yml --syntax-check
```

#### dry-run

```
$ ansible-playbook app.yml -C
```

#### 詳細進捗付き

```
$ ansible-playbook app.yml -vvv
```

# nfsクライアント編

nfs関連のミドルウェアをインストールして、任意のNFSをマウントするまで

CentOS6.5。

## roles/app/defaults/main.yml

```
---
  file_mountpoint: /path_to_mountpoint
  file_server: xxx.xxx.xxx.xxx
```

## roles/app/tasks/main.yml
```
  - name: NFSクライアントをインストール
    become: True
    yum: name={{ item }} state=latest
    with_items:
      - nfs-utils
  - name: NFS関連:rpcbind
    become: True
    service: name=rpcbind state=started enabled=yes
  - name: NFS関連:rpcidmapd
    become: True
    service: name=rpcidmapd state=started enabled=yes
  - name: NFS関連:nfslock
    become: True
    service: name=nfslock state=started enabled=yes
  - name: NFS関連:netfs
    become: True
    service: name=netfs state=started enabled=yes
  - name: マウントポイントを作る
    become: True
    file: path={{ file_mountpoint }} state=directory owner=root group=root mode=0755
  - name: fileサーバーをNFSマウントする
    become: True
    mount: name={{ file_mountpoint }} src={{ file_server }}:{{ file_mountpoint }} fstype=nfs state=mounted
```

rootで作業を行いたい部分に become: Trueを指定していますが、環境や状況によって臨機応変に。

```
  - name: fileサーバーをNFSマウントする
    become: True
    mount: name={{ file_mountpoint }} src={{ file_server }}:{{ file_mountpoint }} fstype=nfs state=mounted
```

この記述で、マウントと/etc/fstabへの追加を一緒に行う。

複数回実行してもfstabに行が増殖することはありません