Skip to content

Commit c6fd7c2

Browse files
committed
improve api server task
1 parent fba7f44 commit c6fd7c2

1 file changed

Lines changed: 60 additions & 64 deletions

File tree

tasks/api_server.yml

Lines changed: 60 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
1+
- name: Create dedicated API service user
2+
become: true
3+
ansible.builtin.user:
4+
name: attackmate-api
5+
system: yes
6+
shell: /usr/sbin/nologin
7+
create_home: no
8+
9+
# --- Git checkout ---
10+
111
- name: Git checkout attackmate-api-server
212
ansible.builtin.git:
313
repo: "{{ attackmate_api_server_url }}"
414
dest: "{{ attackmate_api_server_dest }}"
515
version: "{{ attackmate_api_server_version }}"
16+
register: attackmate_api_git
617
tags:
718
- molecule-idempotence-notest
819

20+
# --- Installation ---
21+
922
- name: Install attackmate-api-server with uv
1023
become: true
1124
ansible.builtin.shell:
1225
chdir: "{{ attackmate_api_server_dest }}"
1326
cmd: "uv pip install --python {{ attackmate_dest }}/.venv/bin/python ."
27+
when: attackmate_api_git.changed
28+
changed_when: true
1429
tags:
1530
- molecule-idempotence-notest
16-
17-
- name: Create dedicated API service user
18-
become: true
19-
ansible.builtin.user:
20-
name: attackmate-api
21-
system: yes
22-
shell: /usr/sbin/nologin
23-
create_home: no
31+
notify: Restart attackmate-api
2432

2533
- name: Create symlink for attackmate-api-server executable
2634
become: true
2735
ansible.builtin.file:
2836
src: "{{ attackmate_dest }}/.venv/bin/attackmate-api"
29-
dest: "/usr/local/bin/attackmate-api"
37+
dest: "{{ attackmate_api_bin_path }}"
3038
state: link
3139
force: true
3240

33-
- name: Get site-packages path from the venv
34-
become: true
35-
ansible.builtin.shell:
36-
cmd: "{{ attackmate_dest }}/.venv/bin/python -c 'import site; print(site.getsitepackages()[0])'"
37-
register: venv_site_packages
38-
changed_when: false
39-
40-
- name: Set API package destination path
41-
ansible.builtin.set_fact:
42-
api_package_path: "{{ venv_site_packages.stdout }}/attackmate_api_server"
4341

4442
- name: Create API log directory
4543
become: true
4644
ansible.builtin.file:
4745
path: "{{ attackmate_api_log_dir }}"
4846
state: directory
47+
owner: attackmate-api
48+
group: attackmate-api
4949
mode: '0755'
5050

5151
- name: Ensure SSL directories exist with correct permissions
@@ -60,75 +60,71 @@
6060
- { path: '/etc/ssl/private', mode: '0711' }
6161
- { path: '/etc/ssl/certs', mode: '0755' }
6262

63+
# --- SSL certificate generation ---
64+
6365
- name: Ensure OpenSSL is installed
6466
ansible.builtin.package:
6567
name: openssl
6668
state: present
6769

6870
- name: Generate Private Key
6971
community.crypto.openssl_privatekey:
70-
path: "/etc/ssl/private/attackmate.key"
72+
path: "{{ attackmate_ssl_key_path }}"
7173
type: RSA
7274
size: 4096
7375
owner: root
74-
group: attackmate-api
76+
group: attackmate-api
7577
mode: '0640'
76-
77-
- name: Generate Certificate Signing Request (CSR)
78-
community.crypto.openssl_csr:
79-
path: "/etc/ssl/private/attackmate.csr"
80-
privatekey_path: "/etc/ssl/private/attackmate.key"
81-
common_name: "{{ ansible_host }}"
82-
subject_alt_name: "IP:{{ ansible_host }},DNS:localhost"
78+
# Only regenerate if the key is absent
79+
regenerate: never
80+
notify: Restart attackmate-api
8381

8482
- name: Generate Self-Signed Certificate
8583
community.crypto.x509_certificate:
86-
path: "/etc/ssl/certs/attackmate.pem"
87-
privatekey_path: "/etc/ssl/private/attackmate.key"
88-
csr_path: "/etc/ssl/private/attackmate.csr"
84+
path: "{{ attackmate_ssl_cert_path }}"
85+
privatekey_path: "{{ attackmate_ssl_key_path }}"
8986
provider: selfsigned
87+
selfsigned_not_after: "+825d"
88+
selfsigned_digest: sha256
89+
subject:
90+
CN: "{{ ansible_host }}"
91+
subject_alt_name:
92+
- "IP:{{ ansible_host }}"
93+
- "DNS:localhost"
94+
regenerate: never
95+
notify: Restart attackmate-api
9096

91-
- name: Create .env file in project root
97+
- name: Fix permissions on SSL keys for the service user
9298
become: true
93-
ansible.builtin.copy:
94-
dest: "{{ attackmate_api_server_dest }}/.env"
95-
content: |
96-
SSL_KEY_PATH="/etc/ssl/private/attackmate.key"
97-
SSL_CERT_PATH="/etc/ssl/certs/attackmate.pem"
98-
ATTACKMATE_CONFIG_PATH="/etc/attackmate.yml"
99-
WRITE_PLAYBOOK_LOGS_TO_DISK="{{ attackmate_api_logs_to_disk }}"
100-
LOG_DIR="{{ attackmate_api_log_dir }}"
101-
# USERS='{"username": "<argon2_hash>", ...}' # You need to enter credentials here, hashed with argon2
102-
owner: attackmate-api
99+
ansible.builtin.file:
100+
path: "{{ item.path }}"
101+
owner: root
103102
group: attackmate-api
104-
mode: '0600'
103+
mode: "{{ item.mode }}"
104+
loop:
105+
- { path: '/etc/ssl/private', mode: '0710' }
106+
- { path: "{{ attackmate_ssl_key_path }}", mode: '0640' }
107+
- { path: "{{ attackmate_ssl_cert_path }}", mode: '0644' }
108+
105109

110+
# --- Env file ---
106111

107-
- name: Ensure API log directory is owned by the service user
112+
- name: Create .env file in project root
108113
become: true
109-
ansible.builtin.file:
110-
path: "{{ attackmate_api_log_dir }}"
111-
state: directory
114+
ansible.builtin.template:
115+
src: api-env.j2
116+
dest: "{{ attackmate_api_server_dest }}/.env"
112117
owner: attackmate-api
113118
group: attackmate-api
114-
mode: '0750'
119+
mode: '0600'
120+
notify: Restart attackmate-api
115121

116-
- name: Fix permissions on SSL keys for the service user
117-
become: true
118-
ansible.builtin.file:
119-
path: "{{ item.path }}"
120-
owner: root
121-
group: attackmate-api # Allow the API user to read the key
122-
mode: "{{ item.mode }}"
123-
loop:
124-
- { path: '/etc/ssl/private', mode: '0710' }
125-
- { path: '/etc/ssl/private/attackmate.key', mode: '0640' }
126-
- { path: '/etc/ssl/certs/attackmate.pem', mode: '0644' }
122+
# --- Systemd service ---
127123

128124
- name: Install AttackMate API Systemd service
129125
become: true
130126
ansible.builtin.copy:
131-
dest: /etc/systemd/system/attackmate-api.service
127+
dest: "{{ attackmate_api_service_path }}"
132128
content: |
133129
[Unit]
134130
Description=AttackMate API Server
@@ -138,10 +134,9 @@
138134
Type=simple
139135
User=attackmate-api
140136
Group=attackmate-api
141-
# This tells Pydantic where to look for the .env file
142137
WorkingDirectory={{ attackmate_api_server_dest }}
143-
ExecStart=/usr/local/bin/attackmate-api
144-
Restart=always
138+
ExecStart={{ attackmate_api_bin_path }}
139+
Restart=on-failure
145140
146141
NoNewPrivileges=yes
147142
PrivateTmp=yes
@@ -150,11 +145,12 @@
150145
151146
[Install]
152147
WantedBy=multi-user.target
148+
notify: Restart attackmate-api
153149

154150
- name: Start and enable AttackMate API
155151
become: true
156152
ansible.builtin.systemd:
157153
name: attackmate-api
158-
state: restarted
154+
state: started
159155
enabled: yes
160156
daemon_reload: yes

0 commit comments

Comments
 (0)