Ansibleはサーバーの構成管理をする
- 導入手順
- インストール
- AnsibleのHostsファイルに、対象サーバーの ホスト名 (またはIPアドレス) を書く
- 作る構成を Playbook(YAML形式) に書き実行
- 前提
- ssh接続可能
- Python2インストール済 (普通されてる)
![Screen Shot 2018-05-11 at 23.49.37.png](https://qiita-image-store.s3.amazonaws.com/0/35156/17389b97-67f3-dea0-01f8-abe3c719e418.png)
具体的には
- nginx,apache,mysqlの導入(yumモジュール)
- AWSの各サービスの構成管理(AWS用モジュール)
- ファイル配布、テキスト置換(fileモジュール)
構成を作成し保持する
-
Playbookの実行結果は、
- 失敗して「fatal」
- 変更した「changed」
- そのままで「ok」
- 最初は「changed」
- その後は何回流しても「ok」にする
理想
Command(shell)モジュールは病
- 指定したコマンドを実行する子
- 「changed」または「fatal」のみ返却する
- いつも「ok」と返すようにするための回避策もある (それこそ無意味)
- name : "ruby check"
command: "ruby --version"
failed_when: False # 失敗(fatal)しても「ok」返す
changed_when: False # 変更(changed)しても「ok」返す
Ansibleフォルダ構成
- 私のテスト環境
- 実用していないため、まだプロトタイプです
- これから良くなっていく予定 (別記事にするかも)
- 基本は公式にあるベストプラクティスにする
- Ansible オレオレベストプラクティス取り入れた
ssh設定ファイルの作り方
test_project01開発環境(development)の例
- ansible.cfg
[ssh_connection]
ssh_args = -F "{{ project_name }}/ssh_config_{{ project_env }}"
- test_project01/hosts_development
[web]
web-01
[all:vars]
project_name="test_project01"
project_env="development"
- test_project01/ssh_config_development
Host web-01
User tetsuya
HostName 127.0.0.1
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
- test_project01/site.yml (Playbook)
- hosts: web
become: yes
user: tetsuya
vars_files:
# role > common-vars > host_vars > group_vars の順に優先
- ../common-vars/common-vars.yml
roles:
- name: ../common-roles/common
- name: test-role
- 実行
# ansible.cfgのあるフォルダで実行する(test_project01の1つ上)
ansible-playbook -i test_project01/hosts_development test_project01/site.
yml -v
設定ファイル
- ansible.cfg
- 自分で作る
- Ansible-playbook実行時、下記の順に読む
- カレント
- 環境変数:ANSIBLE_CONFIG
- ホームディレクトリ
- /etc/ansible/ansible.cfg
変数
-
使うフォルダと命名規則を先に決めとく
-
優先順
- 各Role
- common-vars
- host_vars
- group_vars
-
同一ファイル内の重複はAnsibleが見つけて、Playbook実行時に警告出してくれる
- 別ファイルの場合は、問答無用で上書きする
[WARNING]: While constructing a mapping from /Users/tetsuya/Yama/ansible/common-vars/common-vars.yml, line 1, column
1, found a duplicate dict key (message). Using last defined value only.
チュートリアル
-
Ansibleをはじめる人に
- 即刻やれる
-
Ansible Tutorial
- serverspecも
私も
インストール
- Vagrantfile
Vagrant.configure(2) do |config|
config.vm.define "controller" do |node|
node.vm.box = "centos7_x64"
node.vm.hostname = "controller"
node.vm.network :private_network, ip: "192.168.101.100"
node.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2210
end
config.vm.define "target" do |node|
node.vm.box = "centos7_x64"
node.vm.hostname = "target"
node.vm.network :private_network, ip: "192.168.101.200"
node.vm.network :forwarded_port, id: "ssh", guest: 80, host: 8000
node.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2220
end
end
# 前提
vagrant up
vagrant status # running
ssh -p 2210 root@127.0.0.1 # passwordは "vagrant" vagrant sshも可
Python --version # Python 2.7.5
# インストール
yum install ansible
ansible --version # ansible 2.4.2.0
# sudo su - # root化(vagrant ssh)
umask # 0022
mkdir -p /work/ansible/test1 # Ansibleフォルダ(プロジェクトtest1用)
cd /work/ansible/test1
echo 192.168.101.100 >hosts # hosts(Inventoryファイル)作成
echo 192.168.101.200 >hosts
# ssh設定
ssh-keygen -t rsa # 秘密鍵作成
ssh-copy-id root@192.168.101.100 # 自分(controller)に秘密鍵送信
ssh-copy-id root@192.168.101.200 # targetに
# 疎通
ansible -i hosts 192.168.101.100 -m ping # 自分(controller)にAnsibleからping送信
ansible -i hosts 192.168.101.200 -m ping # targetに
ansible -i hosts 192.168.101.* -m ping # 両方に
# ↑秘密鍵にパスワード指定している場合、1台ずつ入力待ちになって止まる
ansible -i hosts 192.168.101.200 -m yum -s -a name=telnet # yumでtelnetを入れる
# ----> SUCCESSとなり、"changed": trueになる
# インストールされた
ansible -i hosts 192.168.101.200 -m yum -s -a name=telnet # 再度
# ----> SUCCESSとなり、"changed": falseになる
# 既にインストール済みの場合は何もしない
初Playbook
- hosts
[test-servers]
192.168.101.100
192.168.101.200
- Playbook : simple-playbook.yml
---
- hosts: test-servers
become: yes
tasks:
- name: be sure httpd is installed
yum: name=httpd state=installed
- name: be sure httpd is running and enabled
service: name=httpd state=started enabled=yes
become? Ansible1.9からはsudo/suの代わりにbecomeを使う
- 実行
ansible-playbook -i hosts simple-playbook.yml --syntax-check # syntaxチェックのみ
ansible-playbook -i hosts simple-playbook.yml --list-tasks # taskリスト参照のみ
ansible-playbook -i hosts simple-playbook.yml --check # dry-run
ansible-playbook -i hosts simple-playbook.yml # 実行(changed)
ansible-playbook -i hosts simple-playbook.yml # 実行(okに)
service httpd status # runnning
- ホスト情報取る
ansible -m setup -i hosts 192.168.101.100 # 膨大なJSON
- Playbook修正1 : simple-playbook.yml 追記 ( # ADD )
---
- hosts: test-servers
become: yes
tasks:
- name: be sure httpd is installed
yum: name=httpd state=installed
- name: be sure httpd is running and enabled
service: name=httpd state=started enabled=yes
- name: gathering data task example ## ADD
command: echo {{ ansible_enp0s8.ipv4.address }} ## ADD ホスト情報取る
- 実行
ansible-playbook -i hosts simple-playbook.yml # IPv4を取得する (changed)
- Playbook修正2 : simple-playbook.yml 追記 ( # ADD2 )
---
- hosts: test-servers
become: yes
tasks:
- name: be sure httpd is installed
yum: name=httpd state=installed
- name: be sure httpd is running and enabled
service: name=httpd state=started enabled=yes
- name: gathering data task example ## ADD
command: echo {{ ansible_enp0s8.ipv4.address }} ## ADD ホスト情報取る
failed_when: False # ADD2 fatal(失敗)の時もokを返す
changed_when: False # ADD2 changed(変更)の時も
- 実行
ansible-playbook -i hosts simple-playbook.yml # IPv4を取得する (ok)
名前解決
- hosts に名前書く
- ssh_config に名前解決の設定する
- ansible.cfg で ssh_config を読む
- hosts
[test-servers]
# 192.168.101.100 --> controller
controller
192.168.101.200
- ssh_config
Host controller
User root
HostName 192.168.101.100
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
- ansible.cfg
[ssh_connection]
ssh_args = -F ssh_config
同じフォルダに置く
/work/ansible
|--test1
|--ansible.cfg
|--simple-playbook.yml
|--ssh_config
|--hosts
- tree コマンドが無い環境で tree コマンドを実現 \(^o^)/
Ansible-Vaultでパスワード秘匿
作成
ansible-vault create vault_test.yml
# New Vault password:xxxxxx
# Confirm New Vault password:xxxxxx
- vault_test.yml
---
some_key: value1
other_key: value2
編集
ansible-vault edit vault_test.yml # 編集
# Vault password:xxxxx
- vault_test.yml
---
some_key: value1
other_key: value2
one_key: value3 # 追加
暗号化の確認
vim vault_test.yml
- vault_test.yml
$ANSIBLE_VAULT;1.1;AES256
32366165373238636134313832373834626661613532353132373337366134336130643338626339
3362656161626232626434316237646331633933383337350a613361363339343533623936343837
32376362366231626134393763346165316636343863336431333565313530393563356562336335
6164356561666636330a626436363635633736666465333161666332396565346536653639303631
30326461623137643334326161666535613139393638333239313663306637643438376431303965
31633131383665326438653531623630663532663933386164396536653939313838613763643436
383039626137633535363634366364323062
平文ファイル作成
vim vault_test_2.yml # 平文ファイル作成
- vault_test_2.yml
---
new_key: new_value
平文ファイル暗号化
ansible-vault encrypt vault_test_2.yml
# New Vault password:xxxxxx
# Confirm New Vault password:xxxxxx
復号
ansible-vault decrypt vault_test_2.yml
# Vault password:xxxxxx
# Decryption successful
復号確認
vim vault_test_2.yml
- vault_test_2.yml
---
new_key: new_value
上で暗号化したファイルをgroup変数フォルダに入れ、
定義した環境変数を、Playbookを実行した時に参照します
- あくまで検証ですので、パスワード等の扱いは気をつけてください
- git管理の場合は.gitignoreに書きましょう
- 準備
ls -la group_vars/test-servers/
# total 8
# drwxr-xr-x 2 root root 50 May 13 08:03 .
# drwxr-xr-x 3 root root 25 May 13 08:03 ..
# -rw------- 1 root root 549 May 13 07:36 vault_test.yml
# -rw------- 1 root root 23 May 13 07:51 vault_test_2.yml
vim vault-playbook.yml
- vault-playbook.yml
---
- hosts: test-servers
become: yes
tasks:
- name: vault-test
command: echo {{ one_key }}
- 使う
# その1 失敗
ansible-playbook -i hosts vault-playbook.yml
# PLAY [test-servers] ***************************************************************************************************************************
# ERROR! Attempting to decrypt but no vault secrets found
# その2 成功(value3) --ask-vault-pass を付ける
ansible-playbook -i hosts vault-playbook.yml --ask-vault-pass # 成功
# Vault password:xxxxxx
# その3 成功(value3) vaultのパスワードをbuzword.txtに書いておき、 --vault-password-file を付ける
ansible-playbook -i hosts vault-playbook.yml --vault-password-file buzword.txt
sudoするときのパスワード秘匿
わかりづらくてすいません
ほぼ作業ログです
準備
対象サーバー
## sudo用ユーザー作成
useradd testansible # testansibleユーザー追加
grep testansible /etc/passwd # 確認
# testansible:x:1001:1001::/home/testansible:/bin/bash
passwd testansible # パスワード設定 パスワード:test
visudo # wheelグループのユーザーはパスワード付きでsudoできること確認
# --> %wheel ALL=(ALL) ALL
usermod -G wheel testansible # wheelグループに所属させる
su - testansible # testansibleログイン
sudo echo test # sudoしてみる パスワード聞かれる
# test
Ansibleサーバー
# ssh秘密鍵コピー
ssh-copy-id testansible@192.168.101.100
# 変数ファイル編集
ansible-vault edit group_vars/test-servers/vault_test.yml
- group_vars/test-servers/vault_test.yml
---
some_key: value1
other_key: value2
one_key: value3
ansible_ssh_user: testansible # sshユーザー名 (vaultで暗号化)
ansible_sudo_pass: test # sshユーザーのパスワード (vaultで暗号化)
- vault-playbook.yml
---
- hosts: test-servers
become: yes
tasks:
- name: vault-test
command: echo {{ one_key }}
- name: ssh_user_test
command: whoami
- buzword.txt
pass
実行1
Ansibleサーバー
ansible-playbook -i hosts vault-playbook.yml --vault-password-file buzword.txt -vv # 実行
# one_key 取れてて,
# whoami は root になる
実行2
- vault-playbook.yml
---
- hosts: test-servers
become: # yes <--コメントアウトしてみる
tasks:
- name: vault-test
command: echo {{ one_key }}
- name: ssh_user_test
command: whoami
ansible-playbook -i hosts vault-playbook.yml --vault-password-file buzword.txt -vv # 実行
# one_key 取れてて,
# whoami は testansible になる
Role
- RoleがAnsible-GALAXYにある
- 検証中です
Playbook各モジュール
- 検証中です
- 長くなったので別記事にします
Serverspec
- Serverspec はテストツール
- Ansibleと違ってchangeしない
- テストだけする時使う
# インストール
ruby --version # ruby 2.0.0p598 (2014-11-13) [x86_64-linux]
gem list # serverspec なし
gem install serverspec
gem install rake
rake --version # rake, version 12.3.1
rspec --version # RSpec 3.7
gem list # serverspec 2.41.3
# 初期設定
serverspec-init # localhost / SSH
- spec/controller/httpd_spec.rb
require 'spec_helper'
describe package('httpd') do
it { should be_installed }
end
describe service('httpd') do
it { should be_enabled }
it { should be_running }
end
describe port(80) do
it { should be_listening }
end
describe file('/etc/httpd/conf/httpd.conf') do
it { should be_file }
its(:content) { should match /ServerName www.example.com:80/ }
end
- 実行
rake # spec/ホスト名/\*_spec.rb を実行する
ansible_spec (gem)
- Serverspecと統合する(どこかで記載予定)