github twitter email
Ansible을 활용한 운영 자동화 환경 구축
Aug 13, 2019
3 minutes read

요즘 Cloud Native☁️란 말을 많이 듣고 있습니다.
클라우드 컴퓨팅 모델의 장점을 모두 활용하여 서비스를 개발하고 운영하는 방식이죠.
클라우드 환경에서 서비스를 시작한 회사, 많은 준비와 시행착오 끝에 Cloud 환경으로 모든 서비스를 옮긴 회사를 제외하고 서비스 특성, 환경 혹은 리소스 등의 여러가지 이유로 On Premise 환경과 Cloud 환경 모두 서비스를 운영하고 제공하는 경우가 많습니다. (제가 요기 속해있습니다.)

당연한 말이지만 서비스가 많아지면 많아질수록 운영 난이도는 올라갑니다.
관리 포인트가 늘어나고 접근 방식이 달라지며 결정적으로 할일이 많아집니다.

단순반복업무를 좋아하지 않는 저는 업무에서 Ansible을 자주 활용하는 편입니다.

  • 서버 세팅, 설정
  • 서비스 빌드, 배포, 배치
  • 전체 서버에 대한 정보 수집, 전달
  • 빈번하고 귀찮은 불특정다수의 작업들 (동일한 작업이 2회차라면 Playbook을 작성합니다.)
  • .. 등

담당하고 있는 서비스가 IDC 뿐만이 아닌 Cloud(AWS) 환경이 늘어나면서, 동시에 접근해야하는 관리서버(Bastion Host)가 늘어나고 있습니다.

각 관리서버마다 Ansible을 설치하고 사용하는 것도 한두번이기 때문에 이번 기회에 Cloud & On Premise 환경 어디든 접근이 가능한 Ansible Host 를 구성하게 되었습니다.

AWS의 VPC는 격리되어 있습니다.
이에 보통 Bastion Host를 구성하여 내부망에 구성 된 인스턴스에 접근하여 사용합니다.

On-Premise 환경에 있는 Ansible 서버는 특정 AWS Private Host에 접근하기 위해서 SSH ProxyCommand를 활용합니다. (Bastion Host를 SSH 중계서버로 활용하는 방법)

image

위 이미지를 정리하면 다음과 같습니다.

  • Configuration Management Tool: Ansible Core
  • SSH ProxyCommand를 활용 (Only Linux)

Ansible to Windows같은 경우 WinRM 프로토콜로 통신을 합니다.
WinRM은 JumpHost를 따로 지원하지 않습니다.

사전준비

  • Ansible Host와 Bastion Host는 SSH 통신이 되어야 합니다.
  • Ansible Host ➡️ Bastion Host ➡️ Endpoint Host 접속 계정이 미리 정의 되어 있어야 합니다.

전 Ansible 전용 계정을 Bastion Host, Endpoint Host 모두 동일하게 설정하였습니다.

Ansible Host

Ansible Inventory를 Cloud 환경을 고려하여 Dynamic Inventory로 설정하여 사용하고 있습니다. (Dynamic Inventory는 이후 작성 예정)

ansible.cfg

ansible.cfg에 다음 설정들을 추가해줍니다.

cat ~/ansible.cfg
[defaults]
host_key_checking = False
remote_user = ansible_user
private_key_file = /root/.ssh/ansible_user

[ssh_connection]
ssh_args = -F ssh.cfg -o ControlMaster=auto -o ControlPersist=30m -o ForwardAgent=yes
control_path =  ~/.ssh/ansible-%%r@%%h:%%p
  • host_key_checking : endpoint host의 host_key를 확인할지에 대한 옵션입니다.
    Auto Scaling에 대비하여 사용하지 않습니다.
  • remote_user : 사전에 정의한 Ansible 전용 계정을 정의합니다.
  • private_key_file : remote_user의 Private Key 를 정의합니다.

  • ssh_args : endpoint host에 접근할때의 ssh 설정을 정의합니다.
    OpenSSH SSH client 설정입니다.

    • -F ssh.cfg : configfile 을 ssh.cfg로 지정합니다.
    • -o ControlMaster=auto : 자동으로 하나의 네트워크 연결로 여러 세션을 공유
    • -o ControlPersist=30m : 30분동안 초기 연결이 닫혀도 세션이 유지 되도록 설정
    • -o ForwardAgent=yes : 인증 에이전드에 대한 연결을 전달

💡참고
https://docs.ansible.com/ansible/2.4/intro_configuration.html
https://linux.die.net/man/1/ssh
https://linux.die.net/man/5/ssh_config

ssh.cfg

ssh.cfg 설정을 다음과 같이 진행합니다.
AWS의 사설망의 아이피 대역을 중복되지 않게 설정하여 사용합니다. (Peering, DX 등 고려)

cat ~/ssh.cfg
# A Service us-west-2(Oregon) LIVE
Host 10.30.*
  User ansible_user
  ProxyCommand    ssh -W %h:%p -i /root/.ssh/ansible_user ansible_user@11.22.33.44
  StrictHostKeyChecking no 
  IdentityFile    /root/.ssh/ansible_user

# A Service us-west-2(Oregon) Test
Host 10.31.*
  User ansible_user
  ProxyCommand    ssh -W %h:%p -i /root/.ssh/ansible_user ansible_user@55.66.77.88
  StrictHostKeyChecking no 
  IdentityFile    /root/.ssh/ansible_user

# B Service eu-central-1(Frankfurt) LIVE
Host 10.32.*
  User ansible_user
  ProxyCommand    ssh -W %h:%p -i /root/.ssh/ansible_user ansible_user@12.34.56.78
  StrictHostKeyChecking no 
  IdentityFile    /root/.ssh/ansible_user

각 AWS VPC/Subnet 별로의 사설망 대역을 C Class로 Host를 설정하였습니다.
(Ip Range는 다양하게 설정이 가능합니다. 참고_serverfault)

해당 Host로 접근시

  • ansible_user 계정으로 접근
  • ProxyCommand 를 이용하여, ansible_user@bastion_host 를 사용하도록 설정합니다.

Run Example

Target Endpoint IP(10.32.10.32)로 hello-world Playbook을 실행하고자 합니다.

명령어는 다음과 같습니다.

ansible-playbook -i inventory/aws/ec2.py --limit 10.32.10.32 hello-world.yaml

통신 방향은 다음과 같습니다.
> Ansible ➡️ Bastion Host(12.34.56.78) ➡️ Target Host (10.32.10.32)

통신에 대해 조금더 디테일하게 설명하면 다음과 같습니다.
(ansible_user 계정으로 10.32.10.32 서버에 ssh 연결을 시도합니다.)

  1. ssh.cfg에 해당 아이피 대역에 맞는 Host 설정이 있는지 확인합니다. (B Service LIVE)
  2. 해당 설정으로 ssh 연결을 진행합니다.
    Bastion Host(12.34.56.78) 에 ansible_user로 SSH 접속, 경유지로 사용합니다.

마치며

글쓰기는 참 어렵습니다.
특히 오랜만에 작성하려니 더더욱 어렵네요.

그럼 이만 :-)


Tags: ansible ssh

Back to posts