vagrant 로 ansible, puppet, chef를 쓰지 않아도 간단하게 shell 만으로도 배포(provision)이 가능하다. 


아래아 같은 Vagrantfile 예제를 활용한다. 


$ vi Vagrantfile


# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!

VAGRANTFILE_API_VERSION = "2"


Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

    config.vm.box = "precise64"

    config.vm.box_url = "http://files.vagrantup.com/precise64.box"


    config.vm.hostname = "web"

    config.vm.network "private_network", ip: "192.168.1.50"

    config.vm.network :forwarded_port, guest: 9966, host: 3333



    config.vm.provision :shell, :path => "test.sh"

    config.vm.define :testing do |test|

        test.vm.provision :shell, inline: 'echo XXXXX'

    end


end




결과 화면

$ vagrant provision

==> testing: Running provisioner: shell...

    testing: Running: /var/folders/nx/lkzmd37d6fj3sg9kg5flt3yr0000gp/T/vagrant-shell20140714-98395-6wvcso.sh

==> testing: stdin: is not a tty

==> testing: total 12

==> testing: drwxr-xr-x  3 root    root    4096 Sep 14  2012 .

==> testing: drwxr-xr-x 24 root    root    4096 Jul 13 18:18 ..

==> testing: drwxr-xr-x  4 vagrant vagrant 4096 Sep 14  2012 vagrant

==> testing: Running provisioner: shell...

    testing: Running: inline script

==> testing: stdin: is not a tty

==> testing: XXXXX





Posted by '김용환'
,




- devops for developer의 저자가 Ansible 설명자료 

https://austin2014.drupal.org/session/devops-humans-ansible-drupal-deployment-victory



Posted by '김용환'
,


https://www.usenix.org/conference/ucms13/summit-program/presentation/gerla

https://www.youtube.com/watch?v=PDRdCqFp2sY



Posted by '김용환'
,


pycon 2014 에서 ansible 관련 발표가 있었다. 

Ansible - Python-Powered Radically Simple IT Automation


https://us.pycon.org/2014/schedule/presentation/152/


https://www.youtube.com/watch?v=Qi0AhK7PMCI



Posted by '김용환'
,

- ansible을 이용하여 오픈 스택을 vagrant에서 돌려서 테스트할 수 있도록 한 자료 

https://github.com/kili/playbooks

http://www.slideshare.net/lorinh/vagrant-ansible-and-openstack-on-your-laptop

Vagrant, Ansible, and OpenStack on your laptop from Lorin Hochstein



- why and how i use it 

https://speakerdeck.com/tonk/ansible-why-and-how-i-use-it



- ssh key rotation with ansible

https://derpops.bike/?p=47



- ansible tutorial 

https://github.com/leucos/ansible-tuto



- ansbile에 twilo를 연동해서 sms 전달받게 하기

https://www.twilio.com/blog/2014/05/ansible-text-messages-notifications-with-twilio-sms.html?utm_source=twitter&utm_medium=social%20-%20organic&utm_campaign=Ansible

Posted by '김용환'
,


디렉토리가 있으면 다른 작업을 하도록 한다. 

stat과 when 모듈을 사용하면 된다. 



- name: If tomcat1 dir exists

  stat: path=/app/tomcat1

  register: tomcat_path


- name: If tomcat1 dir exists

  debug: msg='tomcat1 dir exist'

  when: tomcat_path.stat.exists == true

 

- name: If tomcat1 dir not exists

  debug: msg='tomcat1 did not exist'

  when: tomcat_path.stat.exists == false




<실행>


TASK: [tomcat1 | If tomcat1 dir exists] *************************************** 

ok: [192.168.1.50]


TASK: [tomcat1 | If tomcat1 dir exists] *************************************** 

ok: [192.168.1.50] => {

    "item": "", 

    "msg": "tomcat1 dir exist"

}


TASK: [tomcat1 | If tomcat1 dir not exists] *********************************** 

skipping: [192.168.1.50]





Posted by '김용환'
,

ansible의 특징 (서버관리, 환경 설정 배포, ....  ) 중 내가 좋아하는 기능 중 

특정 서버에 대해서 명령어 실행을 시킬 수 있다. 

단순히 ssh 명령어로 실행시킬 수 있듯.. 별 건 아니지만, ssh 계정을 다 알지 않아도 추상화된 ansible 위에서 실행시키니 편하다는 장점이 있다. 




특정 서버에  ping이나 traceroute 를 실행시킬 수 있다.  


$ ansible -i hosts 192.168.1.50   -m shell -a "ping -c 1 www.google.com"

192.168.1.50 | success | rc=0 >>

PING www.google.com (173.194.127.147) 56(84) bytes of data.

64 bytes from hkg03s13-in-f19.1e100.net (173.194.127.147): icmp_req=1 ttl=63 time=41.4 ms


--- www.google.com ping statistics ---

1 packets transmitted, 1 received, 0% packet loss, time 0ms

rtt min/avg/max/mdev = 41.486/41.486/41.486/0.000 ms



또는 특정 서버에 service 를 실행할 수 있도록 할 수 있다는 점이다. 


$ ansible -i hosts 192.168.1.50   -m service -a "name=tomcat enabled=yes state=restarted"

192.168.1.50 | success >> {

    "changed": true,

    "enabled": true,

    "name": "tomcat1",

    "state": "started"

}




Posted by '김용환'
,


tomcat 설치하는 ansible-playbook 예제는 아래 링크가 짱인듯 하다. 학습하는 것도 좋다. 

이 부분을 좀 더 매끄럽게 다듬으면 될듯. 


https://github.com/ansible/ansible-examples/tree/master/tomcat-standalone



참고로 vagrant up/down시마다 자동으로 tomcat이 실행될 수 있게 하려면 xinet의 도움을 받는 것도 좋은 듯 하다.

https://github.com/ansible/ansible-examples/blob/master/tomcat-standalone/roles/tomcat/files/tomcat-initscript.sh

https://gist.github.com/valotas/1000094



Posted by '김용환'
,


특정 디렉토리가 없으면 생성하게 하는 것을 ansible에서는 이렇게 표현가능하다. 



- name: If exists

  debug: msg='/app/src exists'

  when: check_path.stat.exists


- name: If not exists

  debug: msg='/app/src is not exists, so ansible make /app/src '

  when: check_path.stat.exists == false


- name: If not exists 2

  file: path=/app/src state=directory

  when: check_path.stat.exists == false



<결과>

첫번째 실행


TASK: [tomcat1 | If exists] *************************************************** 

skipping: [192.168.1.50]


TASK: [tomcat1 | If not exists] *********************************************** 

ok: [192.168.1.50] => {

    "item": "", 

    "msg": "/app/src is not exists, so ansible make /app/src "

}


TASK: [tomcat1 | If not exists 2] ********************************************* 

changed: [192.168.1.50]


두번째 실행


TASK: [tomcat1 | If exists] *************************************************** 

ok: [192.168.1.50] => {

    "item": "", 

    "msg": "/app/src exists"

}


TASK: [tomcat1 | If not exists] *********************************************** 

skipping: [192.168.1.50]


TASK: [tomcat1 | If not exists 2] ********************************************* 

skipping: [192.168.1.50]





debug를 빼면 task 하나를 줄일 수 있다.


- name: If exists

  debug: msg='/app/src exists'

  when: check_path.stat.exists


- name: If not exists

  file: path=/app/src state=directory

  when: check_path.stat.exists == false


Posted by '김용환'
,


ansible에서는 whitespace와 indent가 중요하다. 


하나의 indent는 2개의 whitespace 이고 탭은 허용하지 않는다.  만약 이 rule이 어긋나면 다음과 같은 에러가 발생한다. 


$ ansible-playbook -i hosts playbook.yml 

ERROR: Syntax Error while loading YAML script, playbook.yml

Note: The error may actually appear before this position: line 5, column 2


  tasks:

 - name : test

 ^



$ ansible-playbook -i hosts playbook.yml 

ERROR: Syntax Error while loading YAML script, playbook.yml

Note: The error may actually appear before this position: line 6, column 1


  - name : test

action:  command ls -al /home

^



 ansible-playbook -i hosts playbook.yml 

ERROR: Syntax Error while loading YAML script, playbook.yml

Note: The error may actually appear before this position: line 6, column 5


   - name: test

    action:  command ls -al /home

    ^




때로는 vars, tasks, handlers 등을 사용하면서 공통화할 때도 있는데. whitespace를 잘 못 사용하면 정확히 어디서 문제가 발생했는지 찾기 힘들 수 있으니. whitespace와 indent는 잘 유념해야 한다. 


TASK: [common | install packages] ********************************************* 

failed: [192.168.1.50] => (item=zip - git - maven - ant - mysql-server) => {"failed": true, "item": "zip - git - maven - ant - mysql-server"}

msg: this module requires key=value arguments (['pkg=zip', '-', 'git', '-', 'maven', '-', 'ant', '-', 'mysql-server', 'state=latest', 'update_cache=yes'])


FATAL: all hosts have already failed -- aborting




참고로 task 급의 token에서 ':'를 사용할 때는 편하게 사용가능하다. 아래의 예 모두 잘 동작한다. 


예)

  - name  :   1. install Apache

    apt: name=apache2 state=present


  - name: 1. install Apache

    apt: name=apache2 state=present

Posted by '김용환'
,