Ansible, ec2.py 를 이용한 Dynamic Inventory 활용
Ansible 에는 접속 정보와 관련된 정보들을 Inventory 라고 부른다. 접속 호스트, 접속 계정 정보뿐만 아니라 이들을 그룹으로 묶거나 변수 설정도 가능하다.
그런데, 클라우드 시스템과 같이 서버 관련 정보를 API 형식으로 제공할 경우에 일일이 호스트 정보를 파일로 저장할 필요가 없다. 클라우드 시스템에 서버 관련 정보를 호출하며 자동으로 Inventory 정보가 생성되는 기능을 제공하는데 이를 Dynamic Inventory 라고 한다. 이 기능은 클라우드 뿐만 아니라 LDAP 과 같은 인증 시스템에도 활용가능하다.
Ansible 세팅
AWS 클라우드의 Dynamic Inventory를 활용하기 위한 Ansible 을 세팅해 보자. 가장 중요한 ansible.cfg 는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[defaults] inventory = ~/.ansible/inventories/production/ec2.py library = ~/.ansible/library module_utils = ~/.ansible/module_utils roles_path = ~/.ansible/roles #remote_tmp = ~/.ansible/tmp local_tmp = ~/.ansible/tmp #plugin_filters_cfg = /etc/ansible/plugin_filters.yml #forks = 5 #poll_interval = 15 remote_user = ec2-user sudo_user = root #ask_sudo_pass = True #ask_pass = True transport = smart remote_port = 22 host_key_checking = False [privilege_escalation] become=True become_method=sudo become_user=root become_ask_pass=False |
특별히 inventory 에는 AWS 클라우드에 제공하는 Dynamic Inventory 스크립트 위치를 지정해준다. ansible 을 이용한 접속 정보, 실행할 계정에 대한 정보등을 기재한다.
디렉토리는 구조는 대략 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ tree ├── ansible.cfg ├── filter_plugins ├── inventories │ └── production │ ├── ec2.ini │ ├── ec2.py │ ├── group_vars │ │ └── tag_Service_jmeter_server.yml │ ├── hosts │ └── keypairs │ └── test-server.pem ├── library ├── module_utils ├── roles └── tmp |
AWS 클라우드 Dynamic Inventory 파일
AWS 클라우드의 경우에도 Ansible 의 Dinamic Inventory 기능을 제공한다. 작동원리는 AWS 자원 정보를 불러오고 이것을 Ansible 이 인식하는 Inventory 정보를 구성하는 것이다. AWS 자원 정보를 불러오기 위해서 AWS 는 다음과 같은 스크립트와 환경설정 정보를 제공한다.
- https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.py
- https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini
ec2.py 는 AWS 클라우드 시스템에 호스트 관련 정보를 불러오도록 한다. ec2.ini 는 어디, 어떤 정보를 불러올 건지 어떤 내용을 출력할 것인지를 지정할 수가 있다. 예를들면 다음과 같다.
1 2 3 4 5 |
regions = ap-northeast-2 vpc_destination_variable = private_ip_address route53 = False rds = False elasticache = False |
regions 이 기본값은 all 이다. 이러면 모든 리전에 대해서 호스트 정보를 수집할려고 하기 때문에 시간이 오래걸리는 문제가 발생한다. 특정한 리전에 대해서만 수행하도록 지정하는 것이 좋다.
IAM 설정
가장 중요한것이 IAM 설정이다. Ansible 을 실행하는 서버에는 호스트 정보를 불러올수 있는 IAM 권한이 필요하다. 보통 IAM Role 지정이라고 하는데 대략 다음과 같은 Policy 를 만들어 Role 적용을 하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "ec2:Describe*", "elasticache:Describe*", "rds:Describe*", "route53:ListHostedZones", "route53:ListResourceRecordSets" ], "Resource": "*" } ] } |
Access Key, Secret key 를 이용하는 방법도 있지만 권장하지 않는다.
ec2.py 테스트 및 특징
이제 요건이 갖춰졌으니 테스트를 해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ ec2.py --list "tag_Name_com_jenkins_master": [ "10.18.198.155" ], "tag_Name_com_linux": [ "10.18.198.172" ], "tag_Name_com_nat1": [ "10.18.198.205" ], "tag_Name_com_nat2": [ "10.18.198.209" ], |
내용을 보면 위와같은 key 값들을 보게 된다. 집작했겠지만 ec2.py 는 ec2 인스턴스의 tag 를 key 로 지정해준다. tag 뿐만 아니라 ec2 인스턴스의 정보를 key 만들어준다.
이 key들은 Ansible Inventory 의 group 변수로 활용이 가능하다.
ec2 key pair 를 이용한 접속 정보 만들기
ec2.py 에서 key 들은 곧바로 Ansible 의 group 으로 활용 가능하다. 이를 위해서 inventory/production/group_vars 디렉토리에 key 이름으로 yaml 파일을 생성한다. 그리고 다음과 같이 내용을 입력한다.
1 |
ansible_ssh_private_key_file: ~/.ansible/inventories/production/keypairs/test-server.pem |
Ansible이 그룹 접속을 할때에 위 변수를 활용하게 된다. AWS 클라우드 ec2 접속하기 위한 keypair 를 이용하는데 따른 설정이다.
접속 테스트
이제 다 됐다. 다음과 같이 접속 테스트를 한번 해본다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ ansible tag_Service_jmeter_server -m ping [DEPRECATION WARNING]: The TRANSFORM_INVALID_GROUP_CHARS settings is set to allow bad characters in group names by default, this will change, but still be user configurable on deprecation. This feature will be removed in version 2.10. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details [WARNING]: Platform linux on host 10.18.193.62 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.8/reference_appendices/interpreter_discovery.html for more information. 10.18.193.62 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } |
위와같이 나오면 성공한 것이다.