cisco에서 ansbible로 micro service 만든 사례


https://github.com/CiscoCloud/microservices-infrastructure



Overview

Microservices infrastructure is a modern platform for rapidly deploying globally distributed services

Features

  • Mesos cluster manager for efficient resource isolation and sharing across distributed services
  • Marathon for cluster management of long running containerized services
  • Consul for service discovery
  • Docker container runtime
  • Multi-datacenter support
  • High availablity


Posted by '김용환'
,


ansible 발표 후 질문 중. paramiko에 대한 내용이 있어서 공유함.


ansible 1.2.1 이후 부터 ansible은 default로 openSSH를 사용한다. OpenSSH가 ControlPersist를 옵션으로 지원하기 때문이다.  python 구현체인 paramiko를 사용하지 않는다. RHEL 6, CentOS 6, SLES 10, SLES 11 과 같은 오래된 Linux 배포판의 openSSH가 오래된 경우에는 paramiko를 사용해야 한다. 


상기 Linux 배포판에서 Ansible을 설치하면 paramiko를 사용할 수 있도록 처리되어 있다고 한다. 



참조

http://docs.ansible.com/faq.html

http://docs.ansible.com/intro_configuration.html#paramiko-specific-settings




Posted by '김용환'
,

Ansible의 이해와 활용 발표 자료

http://deview.kr/2014/session?seq=15



Ansible.pdf



발표내용중 잘못된 내용을 수정함

- ansible은 pip 뿐 아니라 brew, apt-get, yum 같은 배포툴로 설치 가능

- 오해의 소지 부분 삭제

Posted by '김용환'
,


오늘 Deview 2014에서 기존의 bash script와 ansible의 차이에 대한 질문을 제대로 답변을 못했던 것 같아 정리해 본다. 배포 관점에서는 똑같지만, ansible이 보다 훨씬 쉽게 다룰 수 있고 높은 수준의 개발이 가능한 보완재라 생각한다. 


나는 naver에서 배포시스템의 bash script 만으로는 한계를 느꼈는데, 그 이유를 들면 다음과 같다.

- 소수점 연산

- 병렬 지원

- 수십개의 서비스 프로젝트를 관리하다 보니, 관리할 내용이 너무 많았다. 체계화된 시스템의 한계를 만남

  (모니터링, 배포, 설정, SSL 설정...)

- 지저분해지는 소스

- 쓰레드 비지원

- 설치/실행스크립트 배포


perl을 이용해서 개발해 보니 소스가 굉장히 깔끔해지고 병렬/쓰레드 지원 코드로 성능 이슈를 해결했다. 

bash보다는 높은 수준의 추상화, strict 한 bash script 코딩보다는 perl의 시스템 코딩이 훨씬 깔끔하고 문제 해결이 쉬웠다. 특히 반복적인 코딩에는 고급언어로서 해결을 보았던 것 같다. 


단순한 목적 해결관점에서는 bash script나 ansible이나 동일하다. 그러나 서비스 확장에 따른 다양한 툴/쓰레드/병렬 지원은 필수가 된다. 그럴 때 아주 위력을 발휘한다. bash script로 개발하다 만나는 문제를 provision 툴이 비슷한 부분으로 해결하는 듯 하다. 


- 소수점 연산 지원

- 병렬 배포 지원

- 내부 디렉토리 체계화 (role, playbooks...)

- 모니터링 체계 수립

- 깔끔해지는 소스

- 설치는 provision툴에서 진행하고 실행하는 스크립트만 배포

- 멱등성 (이미 변경을 원하지 않는다면 넘어감. 따라서 skip이 있으니 빠른 작업이 가능)

- 상태 저장 (특정 리눅스의 명령의 결과를 다른 서버에서도 사용할 수 있도록 함)

- 전역 변수화 (서버마다의 변수를 사용할 수 있지만 정의된 모든 서버에서의 변수화가 가능- 전역 변수처럼)

  


게다가 python 이나 perl은 리눅스 기반의 OS에는 모두 깔려 있지 않은가? 이게 가장 큰 장점이기도 한 것 같다. 바로 써먹을 수 있다는 점인듯 하다. 



Posted by '김용환'
,


국외를 기준으로 2013년, 2014년 Ansible이 컨퍼런스 주제로 발표되었던 책과 링크를 공유한다. 


1. 책
Ansible Configuration Management 
http://www.amazon.com/Ansible-Configuration-Management-Daniel-Hall/dp/1783280816/ref=sr_1_1?ie=UTF8&qid=1412000975&sr=8-1&keywords=ansible

Ansible for devops  (leanpub에서 판매 10위)
https://leanpub.com/ansible-for-devops


2. 외국 발표 자료
oscon 2013
http://www.oscon.com/oscon2013/public/schedule/detail/28726

hadoop 2014 japan
http://www.slideshare.net/zzz0982938/hadoop-muti-node-cluster-fabric-ansible

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

pycon 2013
http://in.pycon.org/funnel/2013/53-ansible-configuration-management-simplified

pycon 2013 japan
http://apac-2013.pycon.jp/ja/program/sessions.html#session-15-1110-rooma0765-ja2-ja
https://github.com/takuan-osho/pyconapac2013-ansible-session

velocity 2013
http://velocityconf.com/velocity2013/public/schedule/detail/28115

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

flock 2014
http://fedoramagazine.org/flock-2014-day-2-orchestration-with-ansible-at-fedora-project/

Gluecon 2014
http://devops.com/blogs/using-docker-ansible/

phpconference 2014
http://phpconference.com/2014se/de/sessions/continuous-deployment-ansible

cloudstack conference 2014
http://phpconference.com/2014se/de/sessions/continuous-deployment-ansible

drupal conf 2014
http://www.midwesternmac.com/blogs/jeff-geerling/devops-humans-ansible

zabbix conference 2014
http://www.zabbix.com/img/zabconf2014/presentations/Patrik_Uytterhoeven_Open-Future_Zabbix_Conference_2014.pdf

php benelux 2014
http://conference.phpbenelux.eu/2014/sessions/

openwest conference 2014
http://brainshed.com/blog/entry/180.html
http://brainshed.com/ansible.pdf

djangocon 2014
http://www.confreaks.com/videos/4457-DjangoCon2014-development-with-ansible-and-vms

2014 HighEdWeb Conference
http://2014.highedweb.org/psessions/detail/94ddaa6d-5255-4e05-9eff-4f1413eb8595


Posted by '김용환'
,


ansible에서 copy를 활용하면 jinja2가 적용될 것이라는 기대감이 있다. 파일 확장자명인 j2를 추가해도 동작이 되지 않는다. 자세한 레퍼런스는 아래 정보를 확인한다. 

http://docs.ansible.com/template_module.html




즉 아래와 같은 copy task를 활용하면 index.php.j2에서 사용하는 vars(예, {{ ansible_hostname }},  {{ansible_default_ipv4.address }} 들을 사용할 수 없다.  


  - name: Hello World PHP script

    copy: src=index.php.j2 dest=/var/www/index.php mode=0664

    


따라서 아래와 같이 고쳐야 한다. 


  - name: Hello World PHP script

    template: src=index.php.j2 dest=/var/www/index.php mode=0664

    





참고로, ansible에서 자동으로 생성되는 변수들을 보려면 아래 명령어를 사용한다. 


$ ansible -m setup hostname


만약 host inventory file을 따로 사용하면 아래와 같이 사용한다.


$ ansible -m setup -i hosts 127.0.0.1


127.0.0.1 | success >> {

    "ansible_facts": {

        "ansible_all_ipv4_addresses": [

            "10.0.3.1",

            "172.17.42.1",

            "10.0.2.15"

        ],

        "ansible_all_ipv6_addresses": [

            "fe80::c4c3:d3ff:fedd:7b42",

            "fe80::8855:d1ff:fedb:831e",

            "fe80::a00:27ff:fe88:ca6"

        ],

        "ansible_architecture": "x86_64",

        "ansible_bios_date": "12/01/2006",

        "ansible_bios_version": "VirtualBox",

        "ansible_cmdline": {

            "BOOT_IMAGE": "/vmlinuz-3.8.0-44-generic",

            "quiet": true,

            "ro": true,

            "root": "/dev/mapper/precise64-root"

        },

        "ansible_date_time": {

            "date": "2014-09-10",

            "day": "10",

            "epoch": "1410337463",

            "hour": "08",

            "iso8601": "2014-09-10T08:24:23Z",

            "iso8601_micro": "2014-09-10T08:24:23.937363Z",

            "minute": "24",

            "month": "09",

            "second": "23",

            "time": "08:24:23",

            "tz": "UTC",

            "tz_offset": "+0000",

            "weekday": "Wednesday",

            "year": "2014"

        },

        "ansible_default_ipv4": {

            "address": "10.0.2.15",

            "alias": "eth0",

            "gateway": "10.0.2.2",

            "interface": "eth0",

            "macaddress": "08:00:27:88:0c:a6",

            "mtu": 1500,

            "netmask": "255.255.255.0",

            "network": "10.0.2.0",

            "type": "ether"

        },

        "ansible_default_ipv6": {},

        "ansible_devices": {

            "sda": {

                "holders": [],

                "host": "SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)",

                "model": "VBOX HARDDISK",

                "partitions": {

                    "sda1": {

                        "sectors": "497664",

                        "sectorsize": 512,

                        "size": "243.00 MB",

                        "start": "2048"

                    },

                    "sda2": {

                        "sectors": "2",

                        "sectorsize": 512,

                        "size": "1.00 KB",

                        "start": "501758"

                    },

                    "sda5": {

                        "sectors": "167268352",

                        "sectorsize": 512,

                        "size": "79.76 GB",

                        "start": "501760"

                    }

                },

                "removable": "0",

                "rotational": "1",

                "scheduler_mode": "deadline",

                "sectors": "167772160",

                "sectorsize": "512",

                "size": "80.00 GB",

                "support_discard": "0",

                "vendor": "ATA"

            },

            "sr0": {

                "holders": [],

                "host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",

                "model": "CD-ROM",

                "partitions": {},

                "removable": "1",

                "rotational": "1",

                "scheduler_mode": "deadline",

                "sectors": "2097151",

                "sectorsize": "512",

                "size": "1024.00 MB",

                "support_discard": "0",

                "vendor": "VBOX"

            },

            "sr1": {

                "holders": [],

                "host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",

                "model": "CD-ROM",

                "partitions": {},

                "removable": "1",

                "rotational": "1",

                "scheduler_mode": "deadline",

                "sectors": "2097151",

                "sectorsize": "512",

                "size": "1024.00 MB",

                "support_discard": "0",

                "vendor": "VBOX"

            }

        },

        "ansible_distribution": "Ubuntu",

        "ansible_distribution_major_version": "12",

        "ansible_distribution_release": "precise",

        "ansible_distribution_version": "12.04",

        "ansible_docker0": {

            "active": true,

            "device": "docker0",

            "id": "8000.000000000000",

            "interfaces": [],

            "ipv4": {

                "address": "172.17.42.1",

                "netmask": "255.255.0.0",

                "network": "172.17.0.0"

            },

            "ipv6": [

                {

                    "address": "fe80::8855:d1ff:fedb:831e",

                    "prefix": "64",

                    "scope": "link"

                }

            ],

            "macaddress": "8a:55:d1:db:83:1e",

            "mtu": 1500,

            "promisc": false,

            "stp": false,

            "type": "bridge"

        },

        "ansible_domain": "",

        "ansible_env": {

            "HOME": "/home/vagrant",

            "LANG": "en_US.UTF-8",

            "LC_ALL": "en_US",

            "LC_CTYPE": "en_US.UTF-8",

            "LOGNAME": "vagrant",

            "MAIL": "/var/mail/vagrant",

            "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games",

            "PWD": "/home/vagrant",

            "SHELL": "/bin/bash",

            "SHLVL": "1",

            "SSH_CLIENT": "10.0.2.2 55976 22",

            "SSH_CONNECTION": "10.0.2.2 55976 10.0.2.15 22",

            "SSH_TTY": "/dev/pts/1",

            "TERM": "xterm-color",

            "USER": "vagrant",

            "_": "/bin/sh"

        },

        "ansible_eth0": {

            "active": true,

            "device": "eth0",

            "ipv4": {

                "address": "10.0.2.15",

                "netmask": "255.255.255.0",

                "network": "10.0.2.0"

            },

            "ipv6": [

                {

                    "address": "fe80::a00:27ff:fe88:ca6",

                    "prefix": "64",

                    "scope": "link"

                }

            ],

            "macaddress": "08:00:27:88:0c:a6",

            "module": "e1000",

            "mtu": 1500,

            "promisc": false,

            "type": "ether"

        },

        "ansible_form_factor": "Other",

        "ansible_fqdn": "precise64",

        "ansible_hostname": "precise64",

        "ansible_interfaces": [

            "lo",

            "lxcbr0",

            "docker0",

            "eth0"

        ],

        "ansible_kernel": "3.8.0-44-generic",

        "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_lsb": {

            "codename": "precise",

            "description": "Ubuntu 12.04 LTS",

            "id": "Ubuntu",

            "major_release": "12",

            "release": "12.04"

        },

        "ansible_lxcbr0": {

            "active": true,

            "device": "lxcbr0",

            "id": "8000.000000000000",

            "interfaces": [],

            "ipv4": {

                "address": "10.0.3.1",

                "netmask": "255.255.255.0",

                "network": "10.0.3.0"

            },

            "ipv6": [

                {

                    "address": "fe80::c4c3:d3ff:fedd:7b42",

                    "prefix": "64",

                    "scope": "link"

                }

            ],

            "macaddress": "c6:c3:d3:dd:7b:42",

            "mtu": 1500,

            "promisc": false,

            "stp": false,

            "type": "bridge"

        },

        "ansible_machine": "x86_64",

        "ansible_memfree_mb": 74,

        "ansible_memtotal_mb": 364,

        "ansible_mounts": [

            {

                "device": "/dev/mapper/precise64-root",

                "fstype": "ext4",

                "mount": "/",

                "options": "rw,errors=remount-ro",

                "size_available": 76284248064,

                "size_total": 83366748160

            },

            {

                "device": "/dev/sda1",

                "fstype": "ext2",

                "mount": "/boot",

                "options": "rw",

                "size_available": 173715456,

                "size_total": 238787584

            }

        ],

        "ansible_nodename": "precise64",

        "ansible_os_family": "Debian",

        "ansible_pkg_mgr": "apt",

        "ansible_processor": [

            "Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz",

            "Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz"

        ],

        "ansible_processor_cores": 2,

        "ansible_processor_count": 1,

        "ansible_processor_threads_per_core": 1,

        "ansible_processor_vcpus": 2,

        "ansible_product_name": "VirtualBox",

        "ansible_product_serial": "NA",

        "ansible_product_uuid": "NA",

        "ansible_product_version": "1.2",

        "ansible_python_version": "2.7.3",

        "ansible_selinux": false,

        "ansible_ssh_host_key_dsa_public": "AAAAB3NzaC1kc3MAAACBAJwR6q4VerUDe7bLXRL6ZPTXj5FY66he+WWlRSoQppwDLqrTG73Pa9qUHMDFb1LXN1qgg0p0lyfqvm8ZeN+98rbT0JW6+Wqa7v0K+N82xf87fVkJcXAuU/A8OGR9eVMZmWsIOpabZexd5CHYgLO3k4YpPSdxc6S4zJcOGwXVnmGHAAAAFQDHjsPg0rmkbquTJRdlEZBVJe9+3QAAAIBjYIAiGvKhmJfzDjVfzlxRD1ET7ZhSoMDxU0KadwXQP1uBdlYVEteJQpUTEsA+7kFH7xhtZ/zbK2afEFHriAphTJmz8GqkIR5CJXh3dZspdk2MHCgxkXl5G/iVPLR9UShN+nsAVxfm0gffCqbqZu3Ridt3JwTXQbiDfXO/a6T/eQAAAIEAlsW/i/dUuFbRVO2zaAKwL/CFWT19Al7+njszC5FCJ2deggmF/NIKJUbJwkRZkwL4PY1HYj2xqn7ImhPSyvdCd+IFdw73Pndnjv0luDc8i/a4JUEfna4rzXt1Y5c24J1pEoKA05VicyCBD2z6TodRJEVEFSsa1s8s2p9x6LxwsDw=",

        "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFxsiWE3WImfJcjiWS5asOVoMsn+0gFLU5AgPNs2ATokB7kw00IsB0YGrqClwYNauRRddkYMsi0icJSR60mYNSo=",

        "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDZt46W9slSN3Y6D2f931rijUPCEewhQWmBfGhybuF4qLftfJMuyFcREZkG6UretVI8ZnQn/OMDgbf2DYMzKsRLnz7W5cGy1Mt1pWoG0iCgi2xHzLqOqPYo4mP9/hdZT6pANXapETT55yx8sHAYLAa9NK5Dtyv+QNQ2dUUb1wUTCqgYffLVDgoHvNNDwCwB6biJf6uopqfg2KXvAzcqSa6oaRChJOXjFlM08HebMwkMSzrOXjWbXhFsONy5JuDf3WztCtLMsFrVRHTdDwTh7uL2UQ8Qcky+kP6Wd7G8NlW5RxubYIFpAM0u2SsQIjYOxz+eOfQ8GE3WjvaIBqX05gat",

        "ansible_swapfree_mb": 767,

        "ansible_swaptotal_mb": 767,

        "ansible_system": "Linux",

        "ansible_system_vendor": "innotek GmbH",

        "ansible_user_id": "vagrant",

        "ansible_userspace_architecture": "x86_64",

        "ansible_userspace_bits": "64",

        "ansible_virtualization_role": "guest",

        "ansible_virtualization_type": "virtualbox",

        "module_setup": true

    },

    "changed": false

}


Posted by '김용환'
,



ansible을 이용하여 단순하게 서버에 대해서 reboot, ping 명령어를 내릴 수 있다.

http://docs.ansible.com/modules.html


게다가 hosts의 모든 서버에 대해서 agt-get으로 apache를 설치했는지 service daemon으로 apache2 데몬이 running인지를 확인할 수 있다. 


 ansible all -i hosts --sudo --verbose --module-name=apt --args="name=apache2 state=present"


127.0.0.1 | success >> {

    "changed": false

}




 $ ansible all -i hosts --sudo --verbose --module-name=service --args="name=apache2 state=running"

127.0.0.1 | success >> {

    "changed": false,

    "name": "apache2",

    "state": "started"

}


Posted by '김용환'
,


vagrant 명령어를 실행하여 provision 관련 옵션이 있는지 찾아보면 잘 드러나지 않는다. 


$  vagrant

Usage: vagrant [options] <command> [<args>]


    -v, --version                    Print the version and exit.

    -h, --help                       Print this help.


Common commands:

     box             manages boxes: installation, removal, etc.

     connect         connect to a remotely shared Vagrant environment

     destroy         stops and deletes all traces of the vagrant machine

     global-status   outputs status Vagrant environments for this user

     halt            stops the vagrant machine

     help            shows the help for a subcommand

     init            initializes a new Vagrant environment by creating a Vagrantfile

     login           log in to Vagrant Cloud

     package         packages a running vagrant environment into a box

     plugin          manages plugins: install, uninstall, update, etc.

     provision       provisions the vagrant machine

     rdp             connects to machine via RDP

     reload          restarts vagrant machine, loads new Vagrantfile configuration

     resume          resume a suspended vagrant machine

     share           share your Vagrant environment with anyone in the world

     ssh             connects to machine via SSH

     ssh-config      outputs OpenSSH valid configuration to connect to the machine

     status          outputs status of the vagrant machine

     suspend         suspends the machine

     up              starts and provisions the vagrant environment

     version         prints current and latest Vagrant version


For help on any individual command run `vagrant COMMAND -h`


Additional subcommands are available, but are either more advanced

or not commonly used. To see all subcommands, run the command

`vagrant list-commands`.


$  vagrant list-commands

Below is a listing of all available Vagrant commands and a brief

description of what they do.


box             manages boxes: installation, removal, etc.

connect         connect to a remotely shared Vagrant environment

destroy         stops and deletes all traces of the vagrant machine

docker-logs     outputs the logs from the Docker container

docker-run      run a one-off command in the context of a container

global-status   outputs status Vagrant environments for this user

halt            stops the vagrant machine

help            shows the help for a subcommand

init            initializes a new Vagrant environment by creating a Vagrantfile

list-commands   outputs all available Vagrant subcommands, even non-primary ones

login           log in to Vagrant Cloud

package         packages a running vagrant environment into a box

plugin          manages plugins: install, uninstall, update, etc.

provision       provisions the vagrant machine

rdp             connects to machine via RDP

reload          restarts vagrant machine, loads new Vagrantfile configuration

resume          resume a suspended vagrant machine

rsync           syncs rsync synced folders to remote machine

rsync-auto      syncs rsync synced folders automatically when files change

share           share your Vagrant environment with anyone in the world

ssh             connects to machine via SSH

ssh-config      outputs OpenSSH valid configuration to connect to the machine

status          outputs status of the vagrant machine

suspend         suspends the machine

up              starts and provisions the vagrant environment

version         prints current and latest Vagrant version


그럴 때는 명령어를 주고 -h 옵션을 주면 provision 여부를 확인할 수 있다. 

$ vagrant reload  -h

Usage: vagrant reload [vm-name]


        --[no-]provision             Enable or disable provisioning

        --provision-with x,y,z       Enable only certain provisioners, by type.

    -h, --help                       Print this help


$ vagrant up -h

Usage: vagrant up [options] [name]


Options:


        --[no-]provision             Enable or disable provisioning

        --provision-with x,y,z       Enable only certain provisioners, by type.

        --[no-]destroy-on-error      Destroy machine if any fatal error happens (default to true)

        --[no-]parallel              Enable or disable parallelism if provider supports it

        --provider PROVIDER          Back the machine with a specific provider

    -h, --help                       Print this help


$ vagrant provision -h

Usage: vagrant provision [vm-name] [--provision-with x,y,z]

        --provision-with x,y,z       Enable only certain provisioners, by type.

        --[no-]parallel              Enable or disable parallelism if provider supports it.

    -h, --help                       Print this help



이 명령어를 조합하면 provision에 대한 것을 확인할 수 있다. ansible을 활용하면 ansible-playbook 명령어를 이용해서 provision을 할 수 있다. 


$ vagrant reload --provision

$ vagrant reload --no-provision

$ vagrant up --no-provision

$ vagrant up --provision

$ vagrant provision

$ ansible-playbook -i hosts playbook.yml

Posted by '김용환'
,


ansible 글 내용을 작성하면서 멱등성(idempotent)이란 용어를 쉽게 표현한 곳이 없어서 서술해보았다.



* 멱등성(idempotence) 이란?


연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 멱등성(idempotence) 이라 한다. puppet, chef, ansible 등은 모두 이런 특성을 가지고 있다. 

쉽게 말하면, rest api의 경우 get, head,put, delete 메소드는 멱등성을 가지고 있다. 그러나 post는 상태를 변화시키기 때문에 멱등성이 없다. (status 변화를 준다.)




* ansible 툴에서의 멱등성이란?


여러번 ansible 툴을 사용하더라도 동일한 결과값을 나올 수 있도록 제공되는 형태여야 한다. 즉 매번 다른 결과가 나오거나 에러가 나온다면 비멱등성(non-idempotent) 하다고 할 수 있다. ansible 툴의 거의 대부분의 모듈은 멱등성을 제공한다. 또한 멱등성을 제공하기 위해서는 조건절을 제공하고 있다. 


예를 들자면, 더 깊이 들어가면, 파일/디렉토리를 생성또는 삭제하는 ‘create:’, ‘remove:’ 같은 ansible 모듈을 실행할 때 ‘when:’ 조건절을 이용할 수 있다. 상태가 변경되면 ‘changed_when:’ 또는 ‘failed_when:’을 사용할 수 있다. 대부분의 ansible 모듈이 멱등성(idempotence)를 보장한다라는 의미는 상태(status)를 파악할 수 있다는 의미를 가진다. 


원래 제공한 ansible 모듈은 대부분 멱등성를 제공하나 개발자/시스템 운영자가 만든 ansible 스크립트는 멱등성를 제공하지 못할 수 있다. 따라서 멱등성이 깨지지 않도록 주의해야 한다. 


  


Posted by '김용환'
,


vagrant 사용시 여러 개의 vm을 실행/종료가 가능하다. 아래의 샘플을 잘 이용하면 될 것이다. 

web과 mysql 이라는 가상머신을 만들고 vm의 이름과 provider 이름을 web과 mysql 으로 변경했다. 



# 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.provision :shell, :path => "test.sh"


    config.vm.define :web do |web_config|

        web_config.vm.box = "web"

        web_config.vm.define "foohost" do |foohost|

        end

        web_config.vm.hostname = "web"

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

        web_config.vm.provider :virtualbox do |vb|

            vb.name = "web"

        end

    end


    config.vm.define :mysql do |mysql_config|

        mysql_config.vm.box = "mysql"

        mysql_config.vm.define "foohost" do |foohost|

        end

        mysql_config.vm.hostname = "mysql"

        mysql_config.vm.network "private_network", ip: "192.168.1.51"

        mysql_config.vm.provider :virtualbox do |vb|

            vb.name = "mysql"

        end

    end

end







참고

http://docs.vagrantup.com/v2/virtualbox/configuration.html

https://docs.vagrantup.com/v2/multi-machine/

http://maci0.wordpress.com/2013/11/09/dynamic-multi-machine-vagrantfile/



Posted by '김용환'
,