ansible을 이용하여 ubuntu image에서 oracle java 7을 설치하는 방법이다. 

apt-get은 update_cache를 이용해서 재설치를 피할 수 있는 방법이 있지만, apt-get을 사용하지 않으면 매번 재설치를 해야 하는 번거로움을 피하기 위해서 java_exists 변수를 사용하였다. 

그리고, oracle java 설치시 oracle license를 수락하는 부분도 추가되었다. 



---

  - name: Check if the java compiler exists

    command : java -version

    ignore_errors: True

    register: java_exists


 # - name: Java already installed

 #   command: echo "Java already installed"

 #   when: java_exists.rc == 0


  - name: ensuring add-apt-repository is installed

    apt: pkg=python-software-properties state=latest

    when: java_exists.rc != 0


  - name: adding webupd8 ppa for java7 installer

    apt_repository: repo=ppa:webupd8team/java

    when: java_exists.rc != 0


  - name: updating apt cache

    apt: update_cache=yes

    when: java_exists.rc != 0


  - name: installing java7

    shell: echo debconf shared/accepted-oracle-license-v1-1 select true |

           debconf-set-selections &&

           echo debconf shared/accepted-oracle-license-v1-1 seen true |

           debconf-set-selections &&

           apt-get -y install oracle-java7-installer

    when: java_exists.rc != 0


결과화면


$ vagrant ssh

Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)


 * Documentation:  https://help.ubuntu.com/

Welcome to your Vagrant-built virtual machine.

Last login: Tue Jun 17 21:11:36 2014 from 192.168.1.1

vagrant@web:~$ java -version

java version "1.7.0_60"

Java(TM) SE Runtime Environment (build 1.7.0_60-b19)

Java HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode)




Posted by '김용환'
,


ansible을 사용하면서 좋은 tip&tech가 있어.. 

ansible의 playbook을 실행할 때, 디버깅에 대한 내용을 간단히 서술한다.


1. echo 

아주 간단한 방법으로 register 된 변수를 확인하기 위해서 체크할 수 있다.  


  - name: Java already installed

    command: echo "Java already installed"

    when: java_exists.rc == 0



- name: get currently installed ruby version

  command: ruby -v

  register: result

  ignore_errors: True  


- name: ruby already installed

    command: echo "Not Valid Ruby Version"

    when: result.rc != 0 or result.stdout.split()[1] != ruby_version



2. debug

ansible의 debug는 막강하다. task단위로 debug 출력이 가능하다. 변수 출력을 {{ }} 할 수 있다. 



  - debug: msg="System {{ inventory_hostname}} has uuid {{ ansible_product_uuid }}"


  - shell: java -version

    register: result


  - debug: var=result




결과 화면



TASK: [debug msg="System {{inventory_hostname}} has uuid {{ansible_product_uuid}}"] *** 

ok: [192.168.1.50] => {

    "msg": "System 192.168.1.50 has uuid AA7E7FE6-A763-4436-9A9A-844E4F7DA63B"

}


TASK: [shell java -version] *************************************************** 

changed: [192.168.1.50]


TASK: [debug var=result] ****************************************************** 

ok: [192.168.1.50] => {

    "result": {

        "changed": true, 

        "cmd": "java -version ", 

        "delta": "0:00:00.077996", 

        "end": "2014-06-17 20:42:11.059910", 

        "invocation": {

            "module_args": "java -version", 

            "module_name": "shell"

        }, 

        "rc": 0, 

        "start": "2014-06-17 20:42:10.981914", 

        "stderr": "java version \"1.7.0_60\"\nJava(TM) SE Runtime Environment (build 1.7.0_60-b19)\nJava HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode)", 

        "stdout": "", 

        "stdout_lines": []

    }

}





3. tags

특정 task까지만 실행할 수 있도록 지원하는 tags이다. 


  - name: Check if the java compiler exists

    command : java -version

    ignore_errors: True

    register: java_exists

    tags :

      - debug


  - name: Java already installed

    command: echo "Java already installed"

    when: java_exists.rc == 0


  - name: ensuring add-apt-repository is installed

    apt: pkg=python-software-properties state=latest

    when: java_exists.rc != 0





<결과>

$ ansible-playbook -i hosts playbooks/common/install.yml  --tags debug


PLAY [all] ******************************************************************** 


GATHERING FACTS *************************************************************** 

ok: [192.168.1.50]


TASK: [Check if the java compiler exists] ************************************* 

changed: [192.168.1.50]


PLAY RECAP ******************************************************************** 

192.168.1.50               : ok=2    changed=1    unreachable=0    failed=0   


이것만 가지고는 detail한 정보를 얻을 수 없다. -v 를 함께 사용한다. json 리턴값을 확인할 수 있다. 



$ ansible-playbook -i hosts playbooks/common/install.yml  -v --tags debug


PLAY [all] ******************************************************************** 


GATHERING FACTS *************************************************************** 

ok: [192.168.1.50]


TASK: [Check if the java compiler exists] ************************************* 

changed: [192.168.1.50] => {"changed": true, "cmd": ["java", "-version"], "delta": "0:00:00.080753", "end": "2014-06-17 20:53:37.487990", "rc": 0, "start": "2014-06-17 20:53:37.407237", "stderr": "java version \"1.7.0_60\"\nJava(TM) SE Runtime Environment (build 1.7.0_60-b19)\nJava HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode)", "stdout": ""}


PLAY RECAP ******************************************************************** 

192.168.1.50               : ok=2    changed=1    unreachable=0    failed=0   



참고로 현재 나온 ansible 1.5 버전으로는 debug와 tags는 같이 사용할 수 없는 듯 하다. 



4. step

ansible 1.1부터는 step을 사용할 수 있다. 마치 c compile 후 하나씩 실행해보는 stack trace를 찾아가볼 수 있다는 장점이 있다. 


$ ansible-playbook -i hosts playbooks/common/install.yml  --step



PLAY [all] ******************************************************************** 


GATHERING FACTS *************************************************************** 

ok: [192.168.1.50]

Perform task: Check if the java compiler exists (y/n/c): 



그리고, 1.2부터는 특정 task 부터 시작할 수 있다. 


$ ansible-playbook -i hosts playbooks/common/install.yml --step --start-at-task='ensuring add-apt-repository is installed'


PLAY [all] ******************************************************************** 


GATHERING FACTS *************************************************************** 

ok: [192.168.1.50]

Perform task: ensuring add-apt-repository is installed (y/n/c): 



5. ansible-playbook 디버그 하기


-vvvv 옵션을 추가하면 fail 난 부분에 대한 자세한 정보를 얻어올 수 있다. 리모트 서버에 어떤 옵션을 사용했는지. 어떤 디렉토리에 파일 복사가 일어났는지 확인할 수 있다. 


$ ansible-playbook -i hosts playbook.yml  -vvvv


PLAY [all] ******************************************************************** 


GATHERING FACTS *************************************************************** 

<192.168.1.50> ESTABLISH CONNECTION FOR USER: vagrant

<192.168.1.50> REMOTE_MODULE setup

<192.168.1.50> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/knight/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '192.168.1.50', "/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1406524187.02-199513811197131 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1406524187.02-199513811197131 && echo $HOME/.ansible/tmp/ansible-tmp-1406524187.02-199513811197131'"]

<192.168.1.50> PUT /var/folders/nx/lkzmd37d6fj3sg9kg5flt3yr0000gp/T/tmpRc60qB TO /home/vagrant/.ansible/tmp/ansible-tmp-1406524187.02-199513811197131/setup

<192.168.1.50> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/knight/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '192.168.1.50', u"/bin/sh -c 'LC_CTYPE=en_US.UTF-8 LANG=en_US.UTF-8 /usr/bin/python /home/vagrant/.ansible/tmp/ansible-tmp-1406524187.02-199513811197131/setup; rm -rf /home/vagrant/.ansible/tmp/ansible-tmp-1406524187.02-199513811197131/ >/dev/null 2>&1'"]

ok: [192.168.1.50]


TASK: [test] ****************************************************************** 

<192.168.1.50> ESTABLISH CONNECTION FOR USER: vagrant

<192.168.1.50> REMOTE_MODULE command ls -al /usr/local

<192.168.1.50> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/knight/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '192.168.1.50', "/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1406524188.43-148131729811675 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1406524188.43-148131729811675 && echo $HOME/.ansible/tmp/ansible-tmp-1406524188.43-148131729811675'"]

<192.168.1.50> PUT /var/folders/nx/lkzmd37d6fj3sg9kg5flt3yr0000gp/T/tmpSF2T1h TO /home/vagrant/.ansible/tmp/ansible-tmp-1406524188.43-148131729811675/command

<192.168.1.50> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/knight/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '192.168.1.50', u"/bin/sh -c 'LC_CTYPE=en_US.UTF-8 LANG=en_US.UTF-8 /usr/bin/python /home/vagrant/.ansible/tmp/ansible-tmp-1406524188.43-148131729811675/command; rm -rf /home/vagrant/.ansible/tmp/ansible-tmp-1406524188.43-148131729811675/ >/dev/null 2>&1'"]

changed: [192.168.1.50] => {"changed": true, "cmd": ["ls", "-al", "/usr/local"], "delta": "0:00:00.003512", "end": "2014-07-28 05:09:49.266159", "rc": 0, "start": "2014-07-28 05:09:49.262647", "stderr": "", "stdout": "total 40\ndrwxr-xr-x 10 root root 4096 Sep 14  2012 .\ndrwxr-xr-x 10 root root 4096 Sep 14  2012 ..\ndrwxr-xr-x  2 root root 4096 Sep 14  2012 bin\ndrwxr-xr-x  2 root root 4096 Sep 14  2012 etc\ndrwxr-xr-x  2 root root 4096 Sep 14  2012 games\ndrwxr-xr-x  2 root root 4096 Sep 14  2012 include\ndrwxr-xr-x  3 root root 4096 Sep 14  2012 lib\nlrwxrwxrwx  1 root root    9 Sep 14  2012 man -> share/man\ndrwxr-xr-x  2 root root 4096 Sep 14  2012 sbin\ndrwxr-xr-x  6 root root 4096 Sep 14  2012 share\ndrwxr-xr-x  2 root root 4096 Sep 14  2012 src"}


TASK: [debug var=vagrant.stdout_lines] **************************************** 

<192.168.1.50> ESTABLISH CONNECTION FOR USER: vagrant

ok: [192.168.1.50] => {

    "vagrant.stdout_lines": [

        "total 40", 

        "drwxr-xr-x 10 root root 4096 Sep 14  2012 .", 

        "drwxr-xr-x 10 root root 4096 Sep 14  2012 ..", 

        "drwxr-xr-x  2 root root 4096 Sep 14  2012 bin", 

        "drwxr-xr-x  2 root root 4096 Sep 14  2012 etc", 

        "drwxr-xr-x  2 root root 4096 Sep 14  2012 games", 

        "drwxr-xr-x  2 root root 4096 Sep 14  2012 include", 

        "drwxr-xr-x  3 root root 4096 Sep 14  2012 lib", 

        "lrwxrwxrwx  1 root root    9 Sep 14  2012 man -> share/man", 

        "drwxr-xr-x  2 root root 4096 Sep 14  2012 sbin", 

        "drwxr-xr-x  6 root root 4096 Sep 14  2012 share", 

        "drwxr-xr-x  2 root root 4096 Sep 14  2012 src"

    ]

}


PLAY RECAP ******************************************************************** 

192.168.1.50               : ok=3    changed=1    unreachable=0    failed=0   



Posted by '김용환'
,

MACOS 에서 vagrant와 virtualbox를 설치한다. 

http://knight76.tistory.com/entry/MAC-OS%EC%97%90%EC%84%9C-virtualbox-vagrant-%EC%84%A4%EC%B9%98




1. 설치 

아래 주소에서 ansible을 설치한다. 

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


brew를 이용한다. 

$ brew update

$ brew install ansible


또는 pip를 이용한다. 


$ sudo easy_install pip

$ sudo pip install ansible


pip설치 중 문제(OS X Mavericks)가 나면 아래 내용을 참고 한다.  

http://knight76.tistory.com/entry/clang-error-unknown-argument-mnofusedmadd





2.  Vagrant 파일 수정


precise64를 사용하는 것으로 수정하고 playbook.yml 파일을 가지고 배포하도록 한다. 


# 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.network :public_network

    config.vm.hostname = "web"


    config.vm.provision "ansible" do |ansible|

        ansible.playbook = "playbook.yml"

    end

end



yml에 대해서 궁금하면 아래 링크를 참조한다. 

http://knight76.tistory.com/entry/yaml-yml-%EC%9E%90%EB%A3%8C-%EA%B3%B5%EC%9C%A0





3. playbook.yml 추가


가상서버에 ssh 로 접근해서 ls -al /home 명령어를 실행하고 결과값을 출력하라는 내용이다. 


- hosts: all

  user: vagrant

  sudo: yes

  tasks:

  - name: test

    action:  command ls -al /home

    register: vagrant

  - debug: var=vagrant.stdout_lines





4. 테스트


$ vagrant provision

==> default: Running provisioner: ansible...


PLAY [all] ******************************************************************** 


GATHERING FACTS *************************************************************** 

ok: [default]


TASK: [test] ****************************************************************** 

changed: [default]


TASK: [debug var=vagrant.stdout_lines] **************************************** 

ok: [default] => {

    "vagrant.stdout_lines": [

        "total 12", 

        "drwxr-xr-x  3 root    root    4096 Sep 14  2012 .", 

        "drwxr-xr-x 24 root    root    4096 Jun 13 01:32 ..", 

        "drwxr-xr-x  5 vagrant vagrant 4096 Jun 13 01:32 vagrant"

    ]

}


PLAY RECAP ******************************************************************** 

default                    : ok=3    changed=1    unreachable=0    failed=0   



아래와 같이 나오면 제대로 동작했다는 의미이다.



* 이슈

vagrant-ansible을 사용할 때 Centos 일부 계열은 고민할 필요학 있다. 따라서 처음 사용자는 될 수 있으면 centos 보다는 ubunut 계열을 사용하는 것이 좋은 듯 하다. 


예를 들어 vagrant 이미지를 centos  이미지로 설치했다고 가정하자. vagrant up 명령시 ssh connection timeout이 발생된다. 



$ vagrant up 시 에러..

    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
    default: Warning: Connection timeout. Retrying...
    default: Warning: Connection timeout. Retrying...
^C==> default: Waiting for cleanup before exiting...
^C==> default: Exiting immediately, without cleanup!


그리고, playbook을 실행하면 에러가 발생한다. 


$ ansible-playbook -i hosts setup.xml

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
failed: [192.168.1.50] => {"failed": true, "parsed": false}
invalid output was: SUDO-SUCCESS-sragynknplstvlayqgkszdzjtvbzwjuj
Error: ansible requires a json module, none found!

TASK: [debug msg="the value of foo.txt is "] **********************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/Users/knight/setup.xml.retry

192.168.1.50               : ok=0    changed=0    unreachable=0    failed=1  






명확하게 어떤 에러가 나는지 보려면 ansible 명령어를 이용해보면 더 잘 알 수 있다.. 


$ ansible all -i hosts -m ping

192.168.1.50 | FAILED >> {
    "failed": true,
    "msg": "Error: ansible requires a json module, none found!",
    "parsed": false
}



즉, CentOS 에 python-simplejson 쪽 이슈가 있다.. python-simplejson을 설치해야 한다....



Managed Node Requirements

On the managed nodes, you only need Python 2.4 or later, but if you are running less than Python 2.5 on the remotes, you will also need:

  • python-simplejson



그래서, ansible 예제로 많이 쓰이는 ubuntu (lucid, precise)를 추천한다. 

또한 yum 설치방식보다는 apt-get을 이용한 설치 방식이 귀찮은 일을 최대한 적게 해주는 듯 했다. 

Posted by '김용환'
,


1. 

virtualbox  설치 - OX x host 버전 4.3.10
https://www.virtualbox.org/wiki/Downloads


2.

vagrant 설치 - mac 버전 1.6.3 (2.0이 조만간 나온다고 한다. 기능이 훨씬 좋아져서 기대가 됨)
https://www.vagrantup.com/downloads.html



3. 

특정 디렉토리로 이동 ($ mkdir -p vagrant-test; cd vagrant-test)


1) box image 추가

$ vagrant box add precise64 http://files.vagrantup.com/precise64.box

2) box init

$ vagrant init precise64

3) box up

$ vagrant up


또는 아래와 같이 진행한다. (다운로드 속도가 더 빠르다...)

1) box image 추가

$ vagrant box add hashicorp/precise64

(터미널에서 virtualbox image 선택)

2) box init

$ vagrant init hashicorp/precise64

3) box up

$ vagrant up



4. 연결

$ vagrant ssh




먼가 꼬였거나 이상하다 싶으면 특정 파일들을 삭제하고 다시 진행한다. 

$ rm -rf vagrant-test/.vagrant  (vagrant meta 파일)

$ rm -rf ~/.vagrant.d  (여기에 다운 받은 이미지와 meta 파일이 저장되어 있다.)



Posted by '김용환'
,