Ansible
alpacax.alpacon 컬렉션으로 Alpacon을 통해 플레이북을 실행할 수 있습니다. alpacax.alpacon.exec 연결은 API를 직접 사용하므로 Alpacon CLI가 필요하지 않습니다.
컨트롤러와 토큰 준비
컨트롤러에는 ansible-core 2.15 이상과 Python 3.11 이상이 필요합니다. 컬렉션을 설치하세요.
ansible-galaxy collection install alpacax.alpaconmacOS 컨트롤러에서는 Ansible 실행 전에 다음 값을 설정하세요.
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES애플리케이션과 서비스 토큰을 준비하세요.
- 서버 계정을 애플리케이션에 연결하거나, 사용자 이름을 지정하고 프로비저닝을 켭니다. 최신 에이전트가 설치된 Linux 서버에서는 첫 명령어 실행 시 계정을 생성합니다. 이 계정을
ansible_user로 지정하세요. - 토큰의 scope를 허용하는 전역 역할을 애플리케이션에 부여합니다. 명령어에는
command:create와command:read가 필요하고, 서버 이름으로 조회하려면server:read도 필요합니다. 모듈 복사를 위한 파일 업로드 권한과 파일을 가져오는 작업에 필요한 다운로드 권한도 부여하세요. alpst-서비스 토큰을 요청하고 웹 콘솔에서 슈퍼유저나 해당 요청의 승인자에게 승인을 받습니다. 명령어와 파일 전송 scope는 항상 승인을 기다립니다. 토큰이 활성화되어 있고 사용 가능한 상태인지 확인하세요.- 승인 후 각 대상 서버에 대한 서버 ACL과 플레이북이 사용하는 경로·전송 방향에 맞는 파일 ACL을 추가합니다. 일반 모듈은 실행 전에 서버로 복사되므로 명령어 실행과 업로드 권한이 모두 필요합니다.
- Alpacon Cloud에서는 명령 ACL 관리자에 등록된 관리자에게 토큰의 사전 승인된 명령에 명령어를 추가해 달라고 요청합니다. 이 권한은 워크스페이스 역할과 별개입니다. 연결을 요청하는 화면이 나오면 연결하기를 선택하세요. 자체 호스팅에서는 Ansible이 제출하는 문자열에 맞는 명령어 ACL 규칙을 추가합니다.
파일 전송에는 S3 기반 스토리지가 필요합니다. 작업 대상 경로뿐 아니라 모듈 업로드에 쓰는 임시 경로도 허용하세요. 이 토큰 작업에는 작업 세션이 필요하지 않습니다. 계정, 역할, ACL 설정은 설정 및 API 참조를 참고하세요.
ansible_user를 반드시 지정하세요. 기본값은 서비스 토큰으로 사용할 수 없는 root입니다. ci-deploy처럼 애플리케이션이 소유한 서버 계정으로 설정하세요.
최소 플레이북 실행
서버 UUID와 계정을 실제 값으로 바꾸고 다음 내용을 inventory.ini로 저장하세요.
[web]
web-01 alpacon_server_id=<server-uuid>
[web:vars]
ansible_connection=alpacax.alpacon.exec
ansible_user=ci-deploy워크스페이스 URL을 설정하고 시크릿 저장소에서 승인된 서비스 토큰 키를 주입하세요. 아래 키는 예시 값입니다.
export ALPACON_URL=https://your-workspace.ap1.alpacon.io
export ALPACON_TOKEN='alpst-REPLACE_WITH_SERVICE_TOKEN'다음 내용을 playbook.yml로 저장하세요.
- hosts: web
gather_facts: false
tasks:
- name: Who am I
ansible.builtin.raw: whoami플레이북을 실행하세요.
ansible-playbook -i inventory.ini playbook.yml명령어는 ci-deploy 계정으로 실행됩니다. raw 작업은 모듈을 업로드하지 않고 whoami를 제출하므로 이 확인에는 whoami 명령어 규칙 하나면 됩니다. root 직접 접근은 기본적으로 꺼져 있습니다. ansible_user를 기본값으로 두면 "code": "workspace_direct_root_disabled"가 포함된 400 응답을 받습니다. 오류 본문은 다음 형태입니다(...는 입력 검증 메시지를 뜻합니다).
{"code": "workspace_direct_root_disabled", "field_errors": {"non_field_errors": [...]}}root 직접 접근을 허용한 워크스페이스에서만 이 요청이 application_system_user_not_found 검사까지 도달합니다. ACL에서 root를 허용해도 애플리케이션이 소유한 계정이 되지는 않습니다.
Ansible의 모듈 실행 방식
일반 모듈 작업은 계정의 홈 디렉터리 확인, ~/.ansible/tmp/ 아래 임의의 임시 디렉터리 생성, Python 탐색, 권한 설정, 업로드한 모듈 실행, 임시 파일 삭제를 위한 래퍼 명령어를 제출합니다. 예를 들어 command 모듈은 AnsiballZ_command.py를 업로드합니다. 제출되는 래퍼 명령어마다 일치하는 명령어 규칙이 필요하고, 모듈 업로드에는 임시 경로를 허용하는 파일 ACL이 필요합니다. whoami만 허용하는 좁은 규칙으로는 이런 모듈 작업을 실행할 수 없습니다. 래퍼 명령어는 Ansible과 대상 서버에 따라 달라지므로 운영에 사용하기 전에 통제된 환경에서 한 번 실행하고 실제 문자열을 확인하세요.
연결 옵션
지원하는 항목에 따라 인벤토리 변수, 환경 변수 또는 ansible.cfg에서 설정할 수 있습니다. 아래 INI 항목은 [alpacon_connection]에 넣습니다. remote_user만 [defaults]에 넣습니다.
| 인벤토리 변수 | 환경 변수 | INI 항목 | 기본값 또는 용도 |
|---|---|---|---|
alpacon_url | ALPACON_URL | url | 워크스페이스 URL, 필수 |
alpacon_token | ALPACON_TOKEN | token | alpst- 서비스 토큰, 필수 |
alpacon_server_id | — | — | 서버 UUID. 이름보다 우선 적용 |
alpacon_server_name | — | — | 생략하면 ansible_host, 이 값도 없으면 인벤토리 호스트 이름 |
alpacon_approval_timeout | ALPACON_APPROVAL_TIMEOUT | approval_timeout | 300초. 0 이하면 승인이 필요할 때 즉시 실패 |
alpacon_ssl_verify | ALPACON_SSL_VERIFY | ssl_verify | true |
alpacon_ca_cert | ALPACON_CA_CERT | ca_cert | CA 인증서 경로 |
ansible_user 또는 ansible_ssh_user | — | remote_user | 기본값은 root. 애플리케이션 계정으로 지정 필요 |
서버 ID가 없으면 이름으로 조회합니다. 여러 서버가 일치하면 Multiple servers match name ..., 조회 가능한 서버가 없으면 Server '<name>' not found in alpacon.이 표시됩니다. 이름이 겹치면 서버 ID를 지정하고, 대상이 조회되지 않으면 토큰의 서버 접근 규칙을 확인하세요.
become으로 권한 상승
become을 사용해도 Ansible은 애플리케이션 계정으로 접속한 뒤 sudo 명령어를 제출합니다. Alpacon Cloud에서는 서비스 토큰의 sudo 위험도가 심각(Critical)보다 낮거나 평가되지 않았으면 허용하고, 심각이면 거부합니다. 단, Advisory 워크스페이스에서는 위험도를 이유로 거부하지 않고 판단을 기록합니다. Advisory가 아니면 워크스페이스의 token_exec 규칙으로 위험도 기준을 더 엄격하게 정할 수 있습니다. 워크스페이스의 sudo 설정도 켜져 있어야 하며, 꺼져 있으면 workspace_sudo_with_mfa_disabled로 거부됩니다. 기본 설정의 자체 호스팅에서는 모든 서비스 토큰 sudo가 sudo_command_not_authorized로 거부됩니다. sudo 정책은 서비스 토큰에 적용되지 않으며 sudo는 사람의 승인을 기다리지 않습니다.
명령어 항목은 sudo 접두사를 포함한 제출 문자열을 허용해야 합니다. Ansible은 임시 경로와 실행마다 생성하는 식별자를 추가하므로 접근 규칙을 설정할 때 실제 문자열을 확인하세요. 플레이북을 통과시키기 위해 sudo *처럼 넓은 항목을 허용하지 마세요. 이 연결은 토큰만 사용하므로 기본 설정의 자체 호스팅에서는 become을 사용할 수 없습니다.
승인 대기와 결과
명령어가 승인을 기다리면 다음 메시지가 표시됩니다.
alpacax.alpacon.exec: command <id> is awaiting approval in the alpacon console; waiting up to <n>s for a decision웹 콘솔에서 승인자에게 검토를 요청하세요. alpacon_approval_timeout은 승인 대기 시간을 정하며, 300초의 실행 제한 시간과는 별개입니다.
| 결과 | 반환 코드와 출력 |
|---|---|
| 성공 | rc: 0 |
| 실행 시간 초과 | rc: 124, stderr에 Command execution timed out |
| 그 밖의 실패 | rc: 1, stderr에 denied, rejected, awaiting_approval 등의 상태 |
| 거부 또는 반려 | rc: 1, stdout에 Command was rejected by the approval policy |
| 승인 대기 시간 초과 | rc: 1, stderr에 awaiting_approval; stdout에 do not resubmit, that would queue a duplicate run 경고 |
Cloud에서 Command was rejected by the approval policy는 명령어 규칙이 없다는 뜻일 수도 있습니다. API는 명령어를 201로 접수한 뒤 rejected로 종료하며, rejection_cause는 command_acl_denied 또는 command_acl_unavailable입니다. 승인 설정을 바꾸기 전에 명령어의 rejection_cause를 확인하세요. 자체 호스팅에서 명령어 ACL로 거부되면 403 api_token_acl_not_allowed가 반환됩니다.
승인 대기 시간이 초과되어도 다시 제출하지 마세요. 원래 명령어는 대기 중이므로 다시 제출하면 두 번 실행될 수 있습니다. 콘솔에서 기존 명령어를 확인하세요.
모듈 작업은 여러 명령어를 제출하며 결과 조회도 요청 수에 포함됩니다. 서버 수가 적어도 서비스 토큰의 기본 한도인 1000/hour에 도달할 수 있습니다. 연결 플러그인은 HTTP 429를 재시도하지 않습니다. 동시 실행 수를 줄이고 Retry-After만큼 기다리세요. 작업을 재시도하기 전에 명령어가 이미 접수되었는지 확인하세요. 상태 조회에 실패했다고 명령어가 실패한 것은 아니며, 다시 제출하면 중복 실행될 수 있습니다.
HTTP 오류, 자격 증명 만료, 계정 거부는 자동화 오류 해결을 참고하세요.