[DevOps] Windows 10에 ansible 이용하기 Computer Tip

DevOps 는 아무리 강조해도 지나치지 않을 만큼 소프트웨어 개발 회사의 경쟁력입니다만,
실제로 현실에 적용하기가 그리 만만치 않습니다.

당장 일거리 들이 쌓여 있지만 그것 처리하기도 바쁜데 언제 

계획 > 개발 > 디버깅 > 개발자테스팅 > 빌드 > 빌드 테스트 > 릴리즈 > 피드백 > 계획

의 과정을 자동화 하려고 시도나 해 본단 말입니까?
암튼 그럼에도 불구하고 DevOps 를 해야만 합니다.

잠시 어제 저녁 극한직업 이라는 다큐를 보게되었는데 방한복이나 방한화를 만드는
공장들이 나왔습니다. 30, 40 년 이상의 경력을 가진 전문가들이
각자의 역할에 잘 분할되어 낭비되는 재료 없이 어느 공정 하나 멈춰서서
전체가 생산에 차질이 없도록 하는 것이었습니다.

위에서 소프트웨어를 생각해보면 그런 공정을 자동화 하여 
생산성을 최대화 한다는 개념인데, 물건을 생산한다고 하면,
하루에 100켤레 신발을 만들 수 있는 회사와,
하루에 1000켤레 신발을 만들 수 있는 회사는 차이가 엄청날 것입니다.

소프트웨어 분야에서는 어디에 얼마큼 자동화를 잘 하느냐에 따라 
같은 인원수를 가지고도 10배가 아니라 100배의 차이가 날 수도 있는 분야라 생각됩니다.

이런 관점에서 ansible은 자동 배포, 테스트 등에 잘 사용되는 툴이라 윈도우에 적용을 한번 해 봅니다.

우선 Linux나 Mac 에서는 ansible의 동작원리가 SSH를 이용합니다.
원격 접속을 하여 필요한 명령 (CLI)을 내리는 것이지요.

그런데 윈도우에 어떻게 적용을 할까 살펴보니, 윈도우에 SSH를 설치하는 것이 아니라,
winrm 이라는 서비스를 이용하더군요.

Ansible의 매뉴얼에 보면 그런 내용이 나옵니다.

그런데 WinRM (Windows Remote Management) 이 이미 윈도우에 있는 것으로 보이네요.
PowerShell 3.0 (현재 Win10 에서는 5.x) 이상, DotNetFramework 4.0 이상에 동작하는 것으로,
또한 Windows Server 2012 이후부터 지원 된다는 것을 보아, 수년 전부터 지원되고 있는 것으로 보입니다.

파워쉘을 윈도우10에서 띄워

Get-Service -Name winrm

이라고 해 보면, 이미 있는데 "Stopped" 멈춘 상태라고 보이는 군요.

이를 ansible에서 사용할 수 있도록 WinRM을 돌리려면,

다음과 같은 네 줄을 복사해서 관리자모드로 띄운 파워쉘 창에서 실행하면 됩니다.

$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file

위와 같이 설치되고 나서,

Get-Service -Name winrm

로 확인해 보면, Status가 "Running" 으로 보이는 것을 확인할 수 있습니다.

서비스가 동작하는지 확인하는 것은

winrm enumerate winrm/config/Listener

명령으로 위와 같이 확인합니다.

이제 간단히 맥 (또는 다른 시스템에서) 등에서 ansible을 이용하려면,

$ cat requirements.txt
ansible==2.7.2
pywinrm==0.3.0

위와 같이 ansible, pywinrm 두 모듈을 파이썬에 설치하면 됩니다.

간단한 테스트를 위하여 다음과 같은 hosts 파일이 있다고 생각합니다.

$ cat hosts
[win10]
192.168.110.110

[win10:vars]
ansible_user=user
ansible_password=pass
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore

[windows:children]
win10

그러면 제일 먼저 ping을 해 보기 위하여,

$ ansible -i hosts win10 -m win_ping
192.168.110.110 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

위와 같이 "ansible -i hosts win10 -m win_ping" 명령으로 확인해 보면,
일단 pong 응답을 하는 군요.

이제 통신은 된 것입니다.

다음으로는 playbook으로 ping을 해 보겠습니다.

$ cat ping.win32.yaml
---
# This playbook uses the win_ping module to test connectivity to Windows hosts
- name: Ping
  hosts: windows

  tasks:
  - name: ping
    win_ping:

위에 처럼 playbook 파일을 하나 만들었습니다.

그다음 실행시켜 봅니다.

$ ansible-playbook -i hosts calc.win32.yaml

PLAY [Run powershell script] ****************************************************************************

TASK [Run calc.exe] *************************************************************************************
fatal: [192.168.110.110]: FAILED! => {"changed": true, "msg": "Executable 'psexec.exe' was not found."}
        to retry, use: --limit @/Users/mcchae/naswork/crpa/ansible/win32/calc.win32.retry

PLAY RECAP **********************************************************************************************
192.168.110.110            : ok=0    changed=0    unreachable=0    failed=1

잘 수행됩니다.
일반적인 ICMP 패킷 차원의 ping 이 아니라, 해당 서비스가 온전하게 응답하는가를 
확인하는 것으로 보면 됩니다. 일반 ping 모듈을 이용하면 ssh 를 이용하는데 반해
win_ping 은 winRM 위에서 돕니다.


이제 whoami 라는 명령을 수행하는 playbook을 하나 만들고,

$ cat whoami.win32.yaml
---
# This playbook uses the win_ping module to test connectivity to Windows hosts
- name: Whoami
  hosts: windows

  tasks:
  - name: whoami
    win_shell: whoami

다음과 같이 실행해봅니다.
이번에는 win_shell 모듈을 이용했습니다.
일반 리눅스나 맥 처럼 command 와 shell 이 있는데
마치 파이썬의 subprocess.Popen 에 shell을 True 로 주는가 아닌가의 차이와 같습니다.
극명한 차이는 shell을 이용하면 shell 에서 직접 명령을 주는 것과 같은 환경변수치환, * 등의 매칭 문자이용,
> 리다이렉트나 | 파이프 등을 이용할 수 있다는 것과 command는 직접 해당 실행파일을 돌리는 것이
차이라고 할 수 있겠지요.

$ ansible-playbook -i hosts whoami.win32.yaml

PLAY [Whoami] *******************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [192.168.110.110]

TASK [whoami] *******************************************************************************************
changed: [192.168.110.110]

PLAY RECAP **********************************************************************************************
192.168.110.110            : ok=2    changed=1    unreachable=0    failed=0

돌렸는데 성공은 했지만, whoami 결과는 안 보입니다.
이럴 때는 -v 옵션을 추가해 줍니다. (-vvv 와 같은 식으로 더 많은 정보를 보여줄 수 있습니다)

$ ansible-playbook -i hosts -v whoami.win32.yaml
No config file found; using defaults
/Users/mcchae/naswork/crpa/ansible/hosts.la-build did not meet host_list requirements, check plugin documentation if this is unexpected
/Users/mcchae/naswork/crpa/ansible/hosts.la-build did not meet yaml requirements, check plugin documentation if this is unexpected

PLAY [Whoami] *******************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [192.168.110.110]

TASK [whoami] *******************************************************************************************
changed: [192.168.110.110] => {"changed": true, "cmd": "whoami", "delta": "0:00:00.359376", "end": "2018-12-06 01:43:51.742310", "rc": 0, "start": "2018-12-06 01:43:51.382934", "stderr": "", "stderr_lines": [], "stdout": "desktop-as6cids\\toor\r\n", "stdout_lines": ["desktop-as6cids\\toor"]}

PLAY RECAP **********************************************************************************************
192.168.110.110            : ok=2    changed=1    unreachable=0    failed=0

이제는 그 결과가 
"stdout_lines": ["desktop-as6cids\\toor"]

에 잘 나온 것으로 보이네요.

$ cat calc.win32.yaml
---
# This playbook tests the script module on Windows hosts
- name: Run powershell script
  hosts: windows
  gather_facts: false
  tasks:
    - name: Run calc.exe
      win_command: calc.exe

calc.exe 와 같은 UI 프로그램을 띄우면, ansible을 block되는 것으로 아는데
위에서 처럼 win_shell 이나 win_command 를 이용해도 잘 뜨고,
정식으로 한다면 win_pexec 로 돌리는게 더 활용할 것이 많다 하네요.

$ cat calc.win32.yaml
---
# This playbook tests the script module on Windows hosts
- name: Run powershell script
  hosts: windows
  gather_facts: false
  tasks:
    - name: Run calc.exe
      win_psexec:
        command: calc.exe


이제 gitlab, jenkins랑 붙이고 이미 만들어 놓은 build.bat 랑 잘 엮으면 테스트를 제외한 DevOps 가 구성되겠군요.


어느 분께는 도움이 되셨기를..

핑백

덧글

댓글 입력 영역

구글애드텍스트