概要
Ansibleについてやってみた
http://dotinstall.com/lessons/basic_ansible
Ansibleとは
サーバの構成管理ツール。サーバに設定したファイルの修正や管理ができる
agentなどクライアント管理にあたり特別なツールが必要ない。また並列で実行でき、高速に動作する
Pythonがインストールされており、鍵認証でのSSHが利用できればOK
Enterpriseツールやサポートなどもあり、有料
構成
ホストにはAnsibleをインストールする
Inventory:どのサーバを管理するか記載する
ansible.cfg:ansibleの全体的な設定を記載する
Playbook:どのような構成とするかを記載する
インストール
root@hostname:/home/shimizu# aptitude install python-pip 以下の新規パッケージがインストールされます: python-pip python-setuptools{a} ... root@hostname:/home/shimizu# pip install ansible ... root@hostname:/home/shimizu# cat /root/.pip/pip.log ... src/MD2.c:31:20: fatal error: Python.h: そのようなファイルやディレクトリはありません compilation terminated. error: command 'gcc' failed with exit status 1 ... root@hostname:/home/shimizu# aptitude install python-dev 以下の新規パッケージがインストールされます: libexpat1-dev{a} python-dev python2.7-dev{a} ... ### 再度インストールしたところうまくいった ### root@hostname:/home/shimizu# pip install ansible ... Successfully installed pycrypto ecdsa Cleaning up... root@hostname:/home/shimizu# ansible --version ansible 1.7.2 ### SSH環境作成 ### ### クライアント ### [root@ip-172-32-0-221 ec2-user]# useradd deploy [root@ip-172-32-0-221 ec2-user]# cat /etc/passwd ... deploy ALL=(ALL) ALL ... [root@ip-172-32-0-221 ec2-user]# su deploy [deploy@ip-172-32-0-221 ec2-user]$ cd /home/deploy/ [deploy@ip-172-32-0-221 .ssh]$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/deploy/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/deploy/.ssh/id_rsa. # 秘密鍵 Your public key has been saved in /home/deploy/.ssh/id_rsa.pub. # 公開鍵 The key fingerprint is: 02:35:0c:37:22:21:06:61:53:50:5e:4f:42:d8:23:9d deploy@ip-172-32-0-221 The key's randomart image is: +--[ RSA 2048]----+ |=**+B**. | |o.o+.E=o | | .o .. | | . | | . S | | . | | | | | | | +-----------------+ [deploy@ip-172-32-0-221 .ssh]$ chmod 600 id_rsa.pub [deploy@ip-172-32-0-221 ~]$ chmod 700 .ssh [deploy@ip-172-32-0-221 ~]$ mv id_rsa.pub authorized_keys ### サーバ ### ### クライアントで作成した秘密鍵をコピーする ### root@hostname:/home/shimizu# vi /root/.ssh/aws_rsa ... root@hostname:/home/shimizu# chmod 600 /root/.ssh/aws_rsa root@hostname:/home/shimizu# ssh -i /root/.ssh/aws_rsa deploy@tech.akat.info Last login: Fri Nov 14 01:14:47 2014 from hostname.sakura.ne.jp __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2014.09-release-notes/ [deploy@ip-172-32-0-221 ~]$
利用方法
### Inventoryファイルの作成 - 正規表現も利用可能### root@hostname:/home/shimizu# mkdir /etc/ansible root@hostname:/home/shimizu# cd /etc/ansible/ root@hostname:/etc/ansible# cat hosts [web] # グループを作成できる 54.64.208.148 ### Inventoryファイルのレスポンス確認 ### root@hostname:/etc/ansible# ansible all -i hosts -m ping -u deploy --private-key=/root/.ssh/aws_rsa 54.64.208.148 | success >> { "changed": false, "ping": "pong" } ### ローカルホストでテストすることも可能 ### root@hostname:/etc/ansible# ansible localhost -m ping localhost | success >> { "changed": false, "ping": "pong" } ### コマンドを実行する ### root@hostname:/etc/ansible# ansible all -i hosts -m command -a "ls /etc/php-fpm-5.5.d" -u deploy --private-key=/root/.ssh/aws_rsa 54.64.208.148 | success | rc=0 >> php-fpm.conf www.conf ### 設定ファイルを作成する ### root@hostname:/etc/ansible# vi /etc/ansible/ansible.cfg [defaults] # リモード接続するときに並行して生成するプロセス数 forks=10 # ログファイルのパス log_path=/var/log/ansible.log ### サーバの情報を取得する ### root@hostname:/etc/ansible# ansible all -i hosts -m setup -u deploy --private-key=/root/.ssh/aws_rsa 54.64.208.148 | success >> { "ansible_facts": { "ansible_all_ipv4_addresses": [ "172.32.0.221" ], "ansible_all_ipv6_addresses": [ "fe80::48d:e7ff:fe9f:8b8f" ], "ansible_architecture": "x86_64", "ansible_bios_date": "06/02/2014", "ansible_bios_version": "4.2.amazon", "ansible_cmdline": { "console": "ttyS0", "root": "LABEL=/" }, "ansible_date_time": { "date": "2014-11-14", "day": "14", "epoch": "1415977044", "hour": "23", "iso8601": "2014-11-14T14:57:24Z", "iso8601_micro": "2014-11-14T14:57:24.426875Z", "minute": "57", "month": "11", "second": "24", "time": "23:57:24", "tz": "JST", "tz_offset": "+0900", "weekday": "Friday", "year": "2014" }, "ansible_default_ipv4": { "address": "172.32.0.221", "alias": "eth0", "gateway": "172.32.0.1", "interface": "eth0", "macaddress": "06:8d:e7:9f:8b:8f", "mtu": 9001, "netmask": "255.255.255.0", "network": "172.32.0.0", "type": "ether" }, "ansible_default_ipv6": {}, "ansible_devices": { "xvda": { "holders": [], "host": "", "model": null, "partitions": { "xvda1": { "sectors": "16773087", "sectorsize": 512, "size": "8.00 GB", "start": "4096" } }, "removable": "0", "rotational": "0", "scheduler_mode": "noop", "sectors": "16777216", "sectorsize": "512", "size": "8.00 GB", "support_discard": "0", "vendor": null } }, "ansible_distribution": "Amazon", "ansible_distribution_major_version": "NA", "ansible_distribution_release": "NA", "ansible_distribution_version": "2014.09", "ansible_domain": "", "ansible_env": { "AWS_AUTO_SCALING_HOME": "/opt/aws/apitools/as", "AWS_CLOUDWATCH_HOME": "/opt/aws/apitools/mon", "AWS_ELB_HOME": "/opt/aws/apitools/elb", "AWS_PATH": "/opt/aws", "AWS_RDS_HOME": "/opt/aws/apitools/rds", "EC2_AMITOOL_HOME": "/opt/aws/amitools/ec2", "EC2_HOME": "/opt/aws/apitools/ec2", "HOME": "/home/deploy", "JAVA_HOME": "/usr/lib/jvm/jre", "LANG": "en_US.UTF-8", "LC_CTYPE": "en_US.UTF-8", "LESSOPEN": "||/usr/bin/lesspipe.sh %s", "LESS_TERMCAP_mb": "\u001b[01;31m", "LESS_TERMCAP_md": "\u001b[01;38;5;208m", "LESS_TERMCAP_me": "\u001b[0m", "LESS_TERMCAP_se": "\u001b[0m", "LESS_TERMCAP_ue": "\u001b[0m", "LESS_TERMCAP_us": "\u001b[04;38;5;111m", "LOGNAME": "deploy", "MAIL": "/var/mail/deploy", "PATH": "/usr/local/bin:/bin:/usr/bin:/opt/aws/bin", "PWD": "/home/deploy", "SHELL": "/bin/bash", "SHLVL": "2", "SSH_CLIENT": "49.212.204.46 35705 22", "SSH_CONNECTION": "49.212.204.46 35705 172.32.0.221 22", "SSH_TTY": "/dev/pts/1", "TERM": "xterm", "USER": "deploy", "_": "/usr/bin/python" }, "ansible_eth0": { "active": true, "device": "eth0", "ipv4": { "address": "172.32.0.221", "netmask": "255.255.255.0", "network": "172.32.0.0" }, "ipv6": [ { "address": "fe80::48d:e7ff:fe9f:8b8f", "prefix": "64", "scope": "link" } ], "macaddress": "06:8d:e7:9f:8b:8f", "mtu": 9001, "promisc": false, "type": "ether" }, "ansible_form_factor": "Other", "ansible_fqdn": "ip-172-32-0-221", "ansible_hostname": "ip-172-32-0-221", "ansible_interfaces": [ "lo", "eth0" ], "ansible_kernel": "3.14.20-20.44.amzn1.x86_64", "ansible_lo": { "active": true, "device": "lo", "ipv4": { "address": "127.0.0.1", "netmask": "255.0.0.0", "network": "127.0.0.0" }, "ipv6": [ { "address": "::1", "prefix": "128", "scope": "host" } ], "mtu": 65536, "promisc": false, "type": "loopback" }, "ansible_machine": "x86_64", "ansible_memfree_mb": 73, "ansible_memtotal_mb": 996, "ansible_mounts": [ { "device": "/dev/xvda1", "fstype": "ext4", "mount": "/", "options": "rw,noatime,data=ordered", "size_available": 5455257600, "size_total": 8318783488 } ], "ansible_nodename": "ip-172-32-0-221", "ansible_os_family": "RedHat", "ansible_pkg_mgr": "yum", "ansible_processor": [ "Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz" ], "ansible_processor_cores": 1, "ansible_processor_count": 1, "ansible_processor_threads_per_core": 1, "ansible_processor_vcpus": 1, "ansible_product_name": "HVM domU", "ansible_product_serial": "NA", "ansible_product_uuid": "NA", "ansible_product_version": "4.2.amazon", "ansible_python_version": "2.6.9", "ansible_selinux": false, "ansible_ssh_host_key_dsa_public": "...", "ansible_ssh_host_key_ecdsa_public": "...", "ansible_ssh_host_key_rsa_public": "...", "ansible_swapfree_mb": 0, "ansible_swaptotal_mb": 0, "ansible_system": "Linux", "ansible_system_vendor": "Xen", "ansible_user_id": "deploy", "ansible_userspace_architecture": "x86_64", "ansible_userspace_bits": "64", "ansible_virtualization_role": "guest", "ansible_virtualization_type": "xen", "module_setup": true }, "changed": false } ### IPアドレスだけを取得する ### root@hostname:/etc/ansible# cat playbook1.yml --- - hosts: all sudo: yes tasks: - name: gathering ip address command: echo {{ ansible_eth0.ipv4.address }} root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass sudo password: ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || _________________ < GATHERING FACTS > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ok: [54.64.208.148] ____________________________ < TASK: gathering ip address > ---------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || changed: [54.64.208.148] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || 54.64.208.148 : ok=2 changed=1 unreachable=0 failed=0 ### Playbookを利用して、ユーザを作成してみる ### root@hostname:/etc/ansible# cat playbook1.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=ansibletest ### tasksはあるべき状態を記載している ### つまり、すでにユーザansibletestがいる場合は何もしない root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass sudo password: ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || _________________ < GATHERING FACTS > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ok: [54.64.208.148] ______________________ < TASK: add a new user > ---------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || changed: [54.64.208.148] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || 54.64.208.148 : ok=2 changed=1 unreachable=0 failed=0 root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass sudo password: ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || _________________ < GATHERING FACTS > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ok: [54.64.208.148] ______________________ < TASK: add a new user > ---------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ok: [54.64.208.148] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || 54.64.208.148 : ok=2 changed=0 unreachable=0 failed=0 # 2回目はchangedが0となっている ### syntax check ### root@hostname:/etc/ansible# ansible-playbook playbook1.yml --syntax-check playbook: playbook1.yml ### タスクを表示 ### root@hostname:/etc/ansible# ansible-playbook playbook1.yml --list-task playbook: playbook1.yml play #1 (all): add a new user ### dry run ### root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass --check sudo password: ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || _________________ < GATHERING FACTS > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ok: [54.64.208.148] ______________________ < TASK: add a new user > ---------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || changed: [54.64.208.148] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || 54.64.208.148 : ok=2 changed=1 unreachable=0 failed=0 ### 変数も利用可能 ### root@hostname:/etc/ansible# cat playbook1.yml --- - hosts: all sudo: yes vars: username: testuser tasks: - name: add a new user user: name={{username}} ### 変数をユーザに入力させることも可能 ### root@hostname:/etc/ansible# cat playbook1.yml --- - hosts: all sudo: yes vars_prompt: username: "Enter username" tasks: - name: add a new user user: name={{username}} root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass --check sudo password: Enter username: : ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ... ### ファイルをおく ### root@hostname:/etc/ansible# cat test.txt this is test root@hostname:/etc/ansible# cat playbook1.yml --- - hosts: all sudo: yes tasks: - name: copy test.txt copy: src=./test.txt dest=/home/ec2-user/test.txt owner=root root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass sudo password: ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || _________________ < GATHERING FACTS > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ok: [54.64.208.148] _____________________ < TASK: copy test.txt > --------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || changed: [54.64.208.148] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || 54.64.208.148 : ok=2 changed=1 unreachable=0 failed=0 ### 状況によって処理を変更する ### root@hostname:/etc/ansible# cat playbook1.yml --- - hosts: all sudo: yes tasks: - name: "command if debian" command: echo {{ ansible_eth0.ipv4.address }} when: ansible_os_family == "Debian" root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass sudo password: ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || _________________ < GATHERING FACTS > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ok: [54.64.208.148] _________________________ < TASK: command if debian > ------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || skipping: [54.64.208.148] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || 54.64.208.148 : ok=1 changed=0 unreachable=0 failed=0
その他
・handlersを利用すれば、サーバに変更があったときのみ最後に1回処理をするなど可能となる
(モジュールをインストール後にapacheを再起動するなど)
・OSによって挙動を変更することも可能
(インストールパッケージ名を変更するなど)
・ansible-pullという応用コマンドもあり、push型のansibleにpull型の機能をもたせている
・モジュールの使い方確認方法 ansible-doc [モジュール名]
・他のPlayBookを読み込むことも可能(- include: other.yml)
参考URL
ansibleを使ってみる-幅広く使い方が記載されておりわかりやすい
http://tdoc.info/blog/2013/04/20/ansible.html
入門ansible(未発表箇所)