본문 바로가기

DevOps/Ansible

[Ansible] 4. vRealize Automation 연동

 

 

 

오늘은 VMware의 자동화 솔루션인 vRealize Automation과 Ansible의 연동을 다뤄보려고 합니다.

우선 크게는 해야할 작업은 다음과 같습니다.

 

  • 앤서블 호스트를 설치합니다. ( ansible 설치 )
  • ansible host의 playbook 실행파일을 수정합니다 ( 디렉토리 추가, 호스트 파일 복사 )
  • ansible host에 config파일을 설정합니다. default값으로 vault password를 사용할 것이고, 기본적인 세팅들을 합니다.
  • 위 내용들은 vmware의 공식홈페이지 document들을 참고합니다.
  • vRA에서 ansible 호스트를 등록합니다.
  • 블루프린트를 작성합니다.

 

현재 제 환경은 다음과 같습니다.

 

vRA Version : 8.4

Ansible Host : Ubuntu 20

Ansible Version : 2.9.6

 

 

 

 

vRA Ansible 사용에 대한 기본적인 개념은

  • vRA Endpoint 등록시에 입력하는 Username / Password or Cert 의 경우 ansible host와 연결하기 위한 Default User 설정입니다추후 블루프린트 ansible 리소스에서 설정하는 username / password는 ansible host의 특별한 계정을 사용하기 위한 설정입니다
  • 일반적으로 계정별로 ansible을 나누어 사용하는 환경이 아니라면 Endpoint 등록시에 사용한 username / password를 그대로 사용하셔도 됩니다 어쨌든 중요한 것은 vRA Endpoint 등록 또는 블루프린트에 입력하는 username / password는 ansible host를 접속하기 위한 계정입니다
  • 그 다음 vault를 이용한 password 등록은 vRA가 ssh를 통해 접속한 ansible host의 계정이 같은 계정으로 배포한 인스턴스에 접근하기 위한 password 입니다 즉 블루프린트에서 지정한 username 계정이 블루프린트에 지정한 패스워드를 통해 vRA에서 ansible host에 접속을 하고 접속한 계정이 배포한 VM에 username 계정으로 접속을 하는데, 이때 사용하는 패스워드는 Vault에 지정한 패스워드 입니다

이 메커니즘이 올바르게 진행되어야 정상적인 인증절차를 통해 ansible을 수행 가능 합니다

아래는 제 환경의 설정입니다

우선 Ansible Host 설정 입니다 vRA와 이후에 배포될 VM 인스턴스 모두와 통신 가능한 대역에 설치했으며… 따로 방화벽정책은 없습니다

  • Ubuntu 20 깨끗한 이미지 이고 아래 커맨드를 통해 설치 하였습니다 추가적으로 sshpass는 따로 설치해야 하는 것로 보여집니다
 

$ apt install ansible

$ apt install sshpass

 

다음으로 ansible.cfg 설정입니다

설정은 모두 문서상 나오는 기본 설정만 하였습니다

$ vi /etc/ansible/ansible.cfg

[defaults]
host_key_checking = False
vault_password_file = /root/.ansible_vault_password.txt
[inventory]
[privilege_escalation]

[paramiko_connection]
record_host_keys = False

[ssh_connection]
ssh_args = -o UserKnownHostsFile=/dev/null

[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]

 

참고

[defaults]

host_key_checking = False
vault_password_file = /root/.ansible_vault_password.txt
[paramiko_connection]
record_host_keys = False
[ssh_connection]
ssh_args = -o UserKnownHostsFile=/dev/null
빨간 색으로 입력한 부분만 포함되면 적용 됩니다.

 

 

Vault Password 파일 설정입니다

$ vi /root/.ansible_vault_password.txt

VMware1!

 

 샘플로 실행해 볼 apache.yaml 플레이북 파일입니다. 여러 사용기준이 있겠지만… 블루프린트에서 groups 프로퍼티를 사용하지 않는다면 일반적으로 hosts: all 로 주어야 정상 실행 됩니다

Hosts에 그룹 설정을 하신 후 groups 프로퍼티를 통해 특정 플레이북 섹션 실행만 가능하기도 합니다. 이 다음으로는 진행한 것은 전에 공유해 드린 ansible-playbook 파일을 치환했습니다. Inventory 파일을 분리하기위함입니다

 

import os
import re
import sys
import time
import json
import traceback

ORGINAL_ANSIBLE_PLAYBOOK_FILE = '/usr/local/bin/ansible-playbook-origin'  # renamed ansible-playbook file
LOG_FILE = '/tmp/vra8-ansible.log' # or (None or False) or another file path
INPUT_DELEMETER='?'
PARAM_DELEMETER=';'
ARRAY_DELEMETER='&'

def getRealType(val):
    if re.search('^[0-9]+$', val): return int(val)
    elif re.search('^[0-9]+\.[0-9]+$', val): return float(val)
    elif ARRAY_DELEMETER in val: return [getRealType(v) for v in val.split(ARRAY_DELEMETER)]
    else: return val

def writeErrorLog(msg):
    with open(LOG_FILE, 'a') as fd: fd.write('----[ %s ]----\nERROR : %s \n\n' % (time.ctime(), msg))
    exit(-1)

if __name__ == '__main__':
    try:
        sys_args = sys.argv[1:]
        vra_args = sys_args[0]
        ans_args = sys_args[1:]
        
        if vra_args[0] == '"' and vra_args[-1] == '"': vra_args = vra_args[1:-1]
        elif vra_args[0] == '"': writeErrorLog('incorrect double quotation')
        elif vra_args[-1] == '"': writeErrorLog('incorrect double quotation')
          
        if INPUT_DELEMETER in vra_args:
            yaml_path, vra_param = vra_args.split(INPUT_DELEMETER)
            vra_param = vra_param.split(PARAM_DELEMETER)
        else:
            yaml_path = vra_args
            vra_param = []
         
        if '--syntax-check' not in ans_args:
            extra_vars = {}
            for param in vra_param:
                kv = re.match('^(?P<key>\w+)=(?P<val>.+)$', param)
                if kv:
                    key, val = kv.groups()
                    extra_vars[key] = getRealType(val)
            if extra_vars: ans_args.append("--extra-vars='%s'" % json.dumps(extra_vars))
        
        ans_args_str = ' '.join(ans_args)
        ans_str = '%s %s' % (yaml_path, ans_args_str)
            
        with open(LOG_FILE, 'a') as fd: fd.write('----[ %s ]----\nVRA-ARGS : %s\nANS-ARGS : %s\nEXECUTE : %s\n\n' % (time.ctime(), vra_args, ans_args_str, ans_str))
        exit(os.system('%s %s' % (ORGINAL_ANSIBLE_PLAYBOOK_FILE, ans_str)))
    
    except Exception as e: writeErrorLog(str(e))

 

 

아래는 테스트를 진행한 블루프린트 입니다

 

formatVersion: 1
inputs: {}
resources:
  ansible:
    type: Cloud.Ansible
    properties:
      host: '${resource.vm.*}'
      osType: linux
      account: test
      username: root
      password: 'VMware1!'
      inventoryFile: '/opt/inventory/${env.deploymentId}/hosts'
      playbooks:
        provision:
          - /opt/playbook/apache.yaml
  net:
    type: Cloud.Network
    properties:
      name: net
      networkType: existing
      constraints:
        - tag: 'net:test'
  vm:
    type: Cloud.Machine
    properties:
      name: vm
      image: ubuntu20
      flavor: medium
      networks:
        - network: '${resource.net.id}'
          assignment: static
      constraints:
        - tag: 'env:vmw01'

 

아파치 설치가 완료되었습니다.

https://github.com/themapisto/ansible-test

 

themapisto/ansible-test

앤서블 리포지토리. Contribute to themapisto/ansible-test development by creating an account on GitHub.

github.com

 

앤서블 플레이북은 제 github를 참고하시면 좋을것 같아요!