일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- REST API
- vault agent
- 파일시스템
- hashicorp
- kv
- Secret Engine
- 구성관리
- 앤서블
- auth methods
- 차분 백업
- 인프라
- SSH OTP
- Role
- key/value
- VIRT
- IAC
- 백업
- 시스템
- devops
- 통합 풀 백업
- 커널 파라미터
- secret engines
- Vault
- 유닉스
- 자동화
- 전체 백업
- 리눅스
- backend storage
- DATA 백업
- SHR
- Today
- Total
클라우드 아카이브
[인프라 테스트] pytest-testinfra를 이용한 인프라 테스트 코드 작성 본문
00. 개요
앤서블을 사용하여 인프라 변경 작업을 수행할 때 해당 변경사항에 대한 테스트 코드를 작성하여 검증하는 방식을 도입하면 좋겠다는 생각을 하게 되었습니다. 또한 CI 도구와 결합하여 앤서블 코드 린트/단위/통합 테스트를 통해 다양한 시나리오를 검증함으로써 코드의 신뢰성을 높일 수 있을 것입니다. 본 포스팅에서는 파이썬에서 제공하는 테스트 프레임워크인 pytest에서 플러그인으로 제공하는 testinfra에 대해 알아보겠습니다.
01. pytest란?
본 포스팅은 testinfra를 학습하는게 목적이므로, pytest에 대한 개념만 간단하게 확인하고 본론으로 들어가겠습니다.
파이썬에서 내장되어 제공되는 테스트 프레임워크로 단위 테스트부터 인수 테스트까지 All-In-One으로 제공
02. pytest-testinfra란?
pytest-testinfra는 pytest 플러그인이며, IT 인프라의 실제 상태를 테스트하는데 사용
주로 구성 관리 도구인 Salt, Ansible, Puppet 등을 적용 후 상태를 테스트하는데 사용됩니다. 본 도구 설계자는 testinfra를 동일 인프라 테스트 도구인 Serverspec과 동일한 기능을 제공하는데 초점을 맞추어 개발했습니다.
03. pytest-testinfra 설치 방식
pytest의 플러그인 형태로 제공되므로 본 플러그인을 직접 설치해야됩니다. pytest의 경우 파이썬 내장 라이브러리이기 때문에 기본적으로 설치되어 있겠지만 본 실습에서는 미설치 상태라고 가정하겠습니다.
# pytest 설치
$ pip install pytest
# testinfra 설치
$ pip install testinfra
# pytest와 testinfra 플러그인이 정상적으로 설치되었는지 확인
$ pip list | grep pytest
pytest 7.1.2
pytest-testinfra 6.7.0
04. pytest-testinfra 적용 대상
위 예제를 통해 pytest-testinfra를 사용하는 방법은 이해되었습니다. 하지만, 적용 대상 서버를 지정하는건 어떻게 해야할지 모른 상태입니다. testinfra는 중앙 서버(예를 들면 앤서블 코어 서버)에서 다양한 환경(BM/VM/Container 등)에서 구동 중인 호스트에 접속하여 테스트할 수 있는 연결 방식을 제공하고 있습니다. 이 중 local, paramiko 연결 방식에 대해 알아보겠습니다. 다른 연결 방식에 대한 내용은 오른쪽 링크를 클릭하여 확인하시면 됩니다.
04-01. Local 연결 방식
localhost에 연결하여 testinfra에 명시된 인프라 상태를 테스트하는 방식입니다. 본 방식은 다음과 같은 CLI 명령어를 통해 테스트할 수 있습니다.
$ py.test --sudo testcode.py
04-02. Paramiko 연결 방식
SSHv2 프로토콜을 통해 테스트 대상 서버에 SSH 연결하여 testinfra에 명시된 인프라 상태를 테스트하는 방식입니다. 본 방식은 다음과 같은 CLI 명령어를 통해 테스트할 수 있습니다. testinfra 플러그인에서는 password 인증 방식을 지원하지 않기 때문에 ssh-agent를 통한 연결 방식을 추천하고 있습니다.
$ py.test --ssh-config=/path/to/ssh_config --hosts=1.1.1.1
05. pytest-testinfra 문법
사실 testinfra는 직관적으로 구성되어 있기 때문에 관련 예제를 통해 바로 문법을 학습해보겠습니다.
def test_passwd_file(File): #
passwd = File("/etc/passwd") #
assert passwd.contains("root") # ”root“
assert passwd.user == "root" # owner root
assert passwd.group == "root" # root
assert passwd.mode == 0644 #
def test_nginx_is_installed(Package):
nginx = Package("nginx")
assert nginx.is_installed # nginx
assert nginx.version.startswith("1.10") # nginx
def test_nginx_running_and_enabled(Service):
nginx = Service("nginx")
assert nginx.is_running # nginx
assert nginx.is_enabled # nginx
파일에서 볼 수 있듯이 파이썬을 개발해본 경험이 있다면 매우 직관적으로 이해할 수 있습니다. 다만 함수 형태로 예제가 제공되기 때문에 어떻게 사용하면 될지는 이해가 쉽지만, 실무에 어떻게 적용할지 감을 익히기엔 어려움이 있습니다. 따라서 파이썬 class를 통해 테스트 코드를 실제 어떻게 작성하면 될지 알아보겠습니다.
import unittest
import testinfra
class Test(unittest.TestCase):
# Before Environment Configuration
def setUp(self):
# local 방식 : localhost (127.0.0.1)에서 테스트를 수행하며 sudo 권한으로 진행
self.host = testinfra.get_host("local://", sudo=True)
# Paramiko 방식 : wheel 그룹에 속한 tech 계정으로 1.1.1.1 서버에 22번 포트로 SSHv2 접속
self.host = testinfra.get_host("paramiko://wheel:tech@1.1.1.1:22")
# After Test process
def tearDown(self) -> None:
return super().tearDown()
# tech 계정과 wheel 그룹이 존재하는지 확인
def test_exist_account_group(self):
viewer_user = self.host.user("tech")
wheel = self.host.group("wheel")
self.assertTrue(wheel.exists)
self.assertTrue(viewer_user.exists)
# ntpd 서비스 상태 확인
def test_systemd_services(host):
assert host.package('ntpd').is_installed == True
ntp = host.service('ntp')
assert ntp.is_running == True
assert ntp.is_enabled == True
if __name__ == "__main__":
unittest.main()
위 코드는 실제 개념 검증을 위해 사용되었던 코드이며 위와 같이 테스트 코드를 작성하시면 됩니다. 위 모듈 이외 다른 모듈을 사용하고자 할 경우 오른쪽 링크를 클릭하여 확인하시면 됩니다.
06. 실행 결과
위 코드를 travis ci를 통해 테스트할 경우 아래와 같은 결과값을 확인할 수 있습니다.
$ python --version
Python 3.6.7
$ pip --version
pip 21.3.1 from /home/travis/virtualenv/python3.6.7/lib/python3.6/site-packages/pip (python 3.6)
install.1
88.58s
$ pip install ansible
install.2
0.94s
$ pip install pytest-testinfra
install.3
0.58s
$ ansible --version
0.67s
$ ansible-playbook ansible/test/test_playbook.yml --syntax-check
[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the
controller starting with Ansible 2.12. Current version: 3.6.7 (default, Jun 12
2019, 02:05:21) [GCC 5.4.0 20160609]. This feature will be removed from
...
PLAY RECAP *********************************************************************
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The command "ansible-playbook ansible/test/test_playbook.yml" exited with 0.
0.54s
$ py.test ansible/test/test_ubuntu.py
============================= test session starts ==============================
platform linux -- Python 3.6.7, pytest-7.0.1, pluggy-0.12.0
rootdir: /home/travis/build/dev-kimdoyoung/IaC_provisioning_openstack_aws
plugins: testinfra-6.8.0
collected 1 item
ansible/test/test_ubuntu.py . [100%]
============================== 1 passed in 0.13s ===============================
The command "py.test ansible/test/test_ubuntu.py" exited with 0.
Done. Your build exited with 0.
07. 마무리
파이썬에서 내장으로 제공하는 테스트 프레임워크인 pytest에서 인프라 테스트 목적의 플러그인 testinfra에 대해 알아봤습니다. 본 플러그인과 CI 도구를 연계하여 TDD 기반의 앤서블 구성 자동화 등을 수행할 수 있습니다.
[출처]
- https://velog.io/@sangyeon217/pytest
- https://testinfra.readthedocs.io/en/latest/