158 lines
5.2 KiB
YAML
158 lines
5.2 KiB
YAML
---
|
|
- name: Create and Configure New LXC Container
|
|
hosts: localhost
|
|
gather_facts: no
|
|
vars_files:
|
|
- "../secrets.yml"
|
|
- "../vars.yml"
|
|
vars_prompt:
|
|
- name: container_name
|
|
prompt: "Enter the new container name"
|
|
private: no
|
|
- name: container_ip
|
|
prompt: "Enter the IP address"
|
|
private: no
|
|
- name: container_id
|
|
prompt: "Enter the Container ID (VMID)"
|
|
private: no
|
|
- name: container_cores
|
|
prompt: "Enter CPU Cores"
|
|
default: "2"
|
|
private: no
|
|
- name: container_memory
|
|
prompt: "Enter Memory in MB"
|
|
default: "256"
|
|
private: no
|
|
|
|
tasks:
|
|
- name: Normalize IP address (append /24 if missing)
|
|
set_fact:
|
|
container_ip_cidr: "{{ container_ip if '/' in container_ip else container_ip + '/24' }}"
|
|
|
|
- name: Create LXC container on Proxmox
|
|
community.general.proxmox:
|
|
api_host: "{{ proxmox_host | default('10.0.0.1') }}"
|
|
api_user: "{{ proxmox_api_user }}"
|
|
api_token_id: "{{ proxmox_api_token_id }}"
|
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
|
node: "{{ proxmox_node }}"
|
|
storage: "{{ proxmox_storage }}"
|
|
ostemplate: '{{ proxmox_storage }}:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst'
|
|
vmid: "{{ container_id }}"
|
|
hostname: "{{ container_name }}"
|
|
password: "{{ lxc_root_password }}"
|
|
pubkey: "{{ my_public_keys | join('\n') }}"
|
|
netif:
|
|
net0: "name=eth0,gw=10.0.0.1,ip={{ container_ip_cidr }},bridge=vmbr0"
|
|
cores: "{{ container_cores }}"
|
|
memory: "{{ container_memory }}"
|
|
swap: 512
|
|
state: present
|
|
unprivileged: yes
|
|
features:
|
|
- nesting=1
|
|
register: proxmox_creation
|
|
|
|
- name: Start the container
|
|
community.general.proxmox:
|
|
api_host: "{{ proxmox_host | default('10.0.0.1') }}"
|
|
api_user: "{{ proxmox_api_user }}"
|
|
api_token_id: "{{ proxmox_api_token_id }}"
|
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
|
vmid: "{{ container_id }}"
|
|
state: started
|
|
|
|
- name: Wait for container to be reachable
|
|
wait_for:
|
|
host: "{{ container_ip_cidr | split('/') | first }}"
|
|
port: 22
|
|
search_regex: OpenSSH
|
|
delay: 10
|
|
timeout: 300
|
|
|
|
- name: Add new host to in-memory inventory (group 'new')
|
|
add_host:
|
|
name: "{{ container_name }}"
|
|
groups: new
|
|
ansible_host: "{{ container_ip_cidr | split('/') | first }}"
|
|
ansible_user: root
|
|
# Removed ansible_ssh_pass - we rely on the injected key
|
|
ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
|
|
|
- name: Secure and Configure New Container
|
|
hosts: new
|
|
gather_facts: no
|
|
vars:
|
|
# We must explicitly use the password here because the 'new' group in inventory might not have it set
|
|
# We use the key for the initial root connection, NOT the password
|
|
# Set ansible_ssh_private_key_file if needed, otherwise it uses the agent
|
|
ansible_user: root
|
|
ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
|
vars_files:
|
|
- "../vars.yml"
|
|
tasks:
|
|
# Updated to verify SSH key works, not password
|
|
- name: Verify we can connect (ping)
|
|
ping:
|
|
|
|
- name: Create user '{{ target_user }}'
|
|
ansible.builtin.user:
|
|
name: '{{ target_user }}'
|
|
shell: /bin/bash
|
|
groups: sudo
|
|
state: present
|
|
|
|
- name: Allow '{{ target_user }}' to use sudo without a password
|
|
ansible.builtin.copy:
|
|
dest: /etc/sudoers.d/90-{{ target_user }}-nopasswd
|
|
content: '{{ target_user }} ALL=(ALL) NOPASSWD: ALL'
|
|
mode: '0440'
|
|
validate: /usr/sbin/visudo -cf %s
|
|
|
|
- name: Set up authorized_keys for '{{ target_user }}'
|
|
ansible.posix.authorized_key:
|
|
user: '{{ target_user }}'
|
|
key: "{{ item }}"
|
|
state: present
|
|
path: /home/{{ target_user }}/.ssh/authorized_keys
|
|
loop: "{{ my_public_keys }}"
|
|
|
|
- name: Lock password for '{{ target_user }}'
|
|
ansible.builtin.user:
|
|
name: '{{ target_user }}'
|
|
password_lock: yes
|
|
|
|
- name: Disallow root login over SSH
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/ssh/sshd_config
|
|
regexp: '^#?PermitRootLogin'
|
|
line: 'PermitRootLogin no'
|
|
validate: /usr/sbin/sshd -t -f %s
|
|
notify: restart sshd
|
|
|
|
- name: Disallow password authentication
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/ssh/sshd_config
|
|
regexp: '^#?PasswordAuthentication'
|
|
line: 'PasswordAuthentication no'
|
|
validate: /usr/sbin/sshd -t -f %s
|
|
notify: restart sshd
|
|
|
|
handlers:
|
|
- name: restart sshd
|
|
ansible.builtin.service:
|
|
name: sshd
|
|
state: restarted
|
|
|
|
- name: Persist Host to Inventory
|
|
hosts: localhost
|
|
gather_facts: no
|
|
tasks:
|
|
- name: Add new host to local hosts.ini file
|
|
ansible.builtin.blockinfile:
|
|
path: "{{ playbook_dir }}/../inventory/hosts.ini"
|
|
block: |
|
|
{{ hostvars[item]['inventory_hostname'] }} ansible_host={{ hostvars[item]['ansible_host'] }}
|
|
insertafter: "^\\[lxc\\]"
|
|
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR HOST {{ hostvars[item]['inventory_hostname'] }}"
|
|
loop: "{{ groups['new'] }}" |