Criar e configurar uma máquina virtual no Proxmox com Ansible
Olá pessoal! Blz?
Nesse artigo eu quero trazer a vocês como eu faço para criar e configurar uma máquina virtual no meu servidor Proxmox em meu HomeLab usando o Ansible, vou deixar também uma task que uso para enviar uma mensagem no Telegram depois que a máquina virtual está pronta para uso. No artigo passado eu mostrei a vocês como criar uma VM “template” Linux para usar no Proxmox, e foi mostrado no artigo que para criar a máquina virtual e só clicar com o botão direito no template e escolher a opção “Clonar”.
Ok certo!!!Mas então por que eu tenho usando o Ansible para isso???? Bem a resposta é: para além de criar, usar o Ansible para deixar essa máquina virtual configurada e pronta para o uso, instalando alguns pacotes básicos.
Eu não deixo isso já pronto na imagem que uso de template pois eu posso querer usar o template para um propósito diferente.
Requisitos para uso do Ansible e Proxmox
Para usarmos o Ansible e Proxmox em conjunto precisamos de alguns itens, alguns deles mostrarei como criar e outros deixarei o link:
API Token: para nos autenticarmos no Proxmox
Template: para realizar o clone, você pode criar seu template seguindo esse artigo
Arquivo de hosts: arquivo com pelo menos o host do Proxmox
Criar uma API Token para autenticação
Criaremos um usuário somente para uso com o Ansible, para criar um usuário na interface web do Proxmox devemos ir em Datacenter -> Permissions -> Users -> Add,
Na tela de cadastro de usuários devemos preencher pelo menos o campo User Name, mas eu gosto de colocar um comentário para identificar o propósito daquele usuário:
Para gerar um API Token no Proxmox vá em Datacenter -> Permissions -> API Token -> Add.
Após clicar em “Add” o token será exibido:
Copie o token e guarde em algum lugar pois não será exibido novamente.
Em seguida, atribua permissões ao usuário ansible e ao token associado. Requer pelo menos essas permissões.
Estrutura de arquivos e pastas de como eu uso
Para nao ficar extenso o artigo eu vou colocar os arquivos principais, mas para ter todos os arquivos vocês podem acessar o repositório no GitHub: create-config-vm-proxmox-ansible
Tenho uma pasta com o nome homelab-ansible onde eu mantenho as roles que uso em meu ambiente HomeLab, ainda está bem no começo mas quero continuar estudando e aplicando no meu ambiente. A estrutura de pastas está da seguinte maneira: uma pasta para as roles, o arquivo de hosts, o arquivo de configuração do Ansible (ansible.cfg) e o arquivo main.yml que eu uso para chamar as roles que eu quero executar, a estrutura de pastas e arquivos ficam da seguinte maneira:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
📦homelab-ansible
┣ 📂roles
┃ ┣ 📂config-vm-linux
┃ ┃ ┣ 📂files
┃ ┃ ┃ ┗ 📜motd
┃ ┃ ┣ 📂tasks
┃ ┃ ┃ ┣ 📜banner.yml
┃ ┃ ┃ ┣ 📜main.yml
┃ ┃ ┃ ┣ 📜packages.yml
┃ ┃ ┃ ┣ 📜ssh.yml
┃ ┃ ┃ ┗ 📜update.yml
┃ ┃ ┗ 📂vars
┃ ┃ ┃ ┗ 📜main.yml
┃ ┣ 📂create-vm-proxmox
┃ ┃ ┣ 📂tasks
┃ ┃ ┃ ┣ 📜create-vm.yml
┃ ┃ ┃ ┣ 📜main.yml
┃ ┃ ┃ ┗ 📜notify_telegram.yml
┃ ┃ ┣ 📂vars
┃ ┃ ┃ ┗ 📜main.yml
┣ 📜ansible.cfg
┣ 📜hosts
┗ 📜main.yml
Para chamar as roles eu uso um arquivo “principal” chamado main.yml onde eu passo as variáveis e tem o seguinte conteúdo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- name: PROXMOX | Create a Linux Virtual Machine
hosts: proxmox
remote_user: root
roles:
- role: create-vm-proxmox
vars:
proxmox_node: pve
api_user: ansible@pam
api_token_id: ansible
storage: vms-storage
api_token_secret: xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
- name: LINUX | Install basic packages
hosts: vms
become: true
roles:
- config-vm-linux
Nas variáveis acima eu inform o usuário, o token ID e o token secret criados no passo anterior.
O arquivo hosts é simples e contém o servidor proxmox e as máquinas virtuais criadas:
1
2
3
4
5
[proxmox]
192.168.1.250
[vms]
lnx-docker-006 ansible_host=192.168.1.106
Criar uma máquina virtual com Ansible
Estou usando roles para criar as máquinas virtuais pois prefiro trabalhar dessa maneira, mas isso não impede que você use as playbooks standalone, a primeira role que cria a máquina virtual tem alguns pontos importantes como variáveis e configurações.
Seguindo a minha estrutura de pastas o conteúdo da role ficará da seguinte forma:
1
2
3
4
5
6
7
📦create-vm-proxmox
┣ 📂tasks
┃ ┣ 📜create-vm.yml
┃ ┣ 📜main.yml
┃ ┗ 📜notify_telegram.yml
┣ 📂vars
┃ ┗ 📜main.yml
Como vocês sabem, cada máquina virtual no Proxmox tem um ID, o ID das minhas máquinas virtuais estão começando em 100 e para a MINHA organização eu sempre associo o IP da máquina virtual com o ID, por exemplo: a máquina virtual com ID 105 terá o IP 192.168.1.105, mas caso não usem dessa forma podem excluir a task Getting the VM ID e Setting the IP.
Na task Print VM IP and Name to HOST file eu adiciono a máquina virtual criada ao meu arquivo de hosts do Ansible, caso você prefira fazer isso de forma manual pode também remover essa task.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
---
- name: Creating the Virtual Machine
become: true
become_user: root
proxmox_kvm:
api_user : "{{ api_user }}"
api_token_id : "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
api_host : "{{ ansible_default_ipv4.address }}"
clone : ubuntu-template
name : "{{ vm_name }}"
node : "{{ proxmox_node }}"
storage : "{{ storage }}"
timeout : 500
- name: Wait for VM to be created
pause:
seconds: 10
- name: Getting the VM ID
shell: qm list | grep "{{ vm_name }}" | awk '{ print $1 }'
register: thevmid
- name: Setting the IP
shell: qm set "{{ thevmid.stdout }}" --ipconfig0 ip=192.168.1.{{ thevmid.stdout }}/24,gw=192.168.1.1
# Config the IP 192.168.1.x and gateway 192.168.1.1
- name: Starting the VM "{{ vm_name }}"
proxmox_kvm:
api_user : "{{ api_user }}"
api_token_id : "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
api_host : "{{ ansible_default_ipv4.address }}"
name : "{{ vm_name }}"
node : "{{ proxmox_node }}"
state : started
- name: Print VM IP and Name to HOST file
ansible.builtin.lineinfile:
path: hosts
line: '{{ vm_name }} ansible_host=192.168.1.{{ thevmid.stdout }}'
delegate_to: localhost
- name: Refresh inventory in memory
meta: refresh_inventory
- name: Wait for VM to be started
pause:
seconds: 50
...
As variáveis são declaradas no arquivo vars/main.yml:
1
2
3
4
5
6
7
---
# vars file for create-vm-proxmox
proxmox_node:
api_token_id:
api_user:
storage:
api_token_secret:
Após a criação da máquina virtual podemos usar uma task para receber uma notificação no Telegram informando que a máquina virtual foi criado, para isso uso o seguinte código:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
- name: Telegram | Send message
community.general.telegram:
token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
api_args:
chat_id: -4xxxxxxxx335
parse_mode: plain
text: |
### Your Server is READY!! ###
--------------------------------------
Server: ""
IP ADDRESS: "192.168.1."
'URL': ssh://[email protected].
--------------------------------------
...
Para integrar com o Telegram é necessário a criação de um bot, vou deixar o link abaixo de como fazer isso, pois precisa passar o token e o chat_id
Configurar uma máquina virtual Linux com Ansible
Na role que uso para configurar a máquina virtual criada ou alguma já existente esta dividida da forma abaixo, lembrando que se tiver alguma task que não queira executar é só comentar no arquivo tasks/main.yml:
1
2
3
4
5
6
7
8
9
10
11
📦config-vm-linux
┣ 📂files
┃ ┗ 📜motd
┣ 📂tasks
┃ ┣ 📜banner.yml
┃ ┣ 📜main.yml
┃ ┣ 📜upgrade.yml
┃ ┣ 📜ssh.yml
┃ ┗ 📜install_packages.yml
┗ 📂vars
┃ ┗ 📜main.yml
main.yml
Arquivo para chamar as tasks dessa role:
1
2
3
4
5
6
7
8
9
10
11
12
13
---
# tasks file for config-vm-linux
- name: LINUX | Config Motd banner
import_tasks: banner.yml
- name: LINUX | Config SSH Server
import_tasks: ssh.yml
- name: LINUX | Install basic packages
import_tasks: install_packages.yml
- name: LINUX | Upgrade SO
import_tasks: upgrade.yml
banner.yml
Task para configurar o motd com o arquivo que está na pasta files/motd:
1
2
3
4
- name: Server | Copy MTOD to server
ansible.builtin.copy:
src: motd
dest: /etc/motd
O arquivo files/motd tem o seguinte banner:
1
2
3
4
5
_ ____ _ _ _ _____ _____ ____
/ \ | _ \ / \ | \ | |_ _| ____/ ___|
/ _ \ | |_) | / _ \ | \| | | | | _| \___ \
/ ___ \| _ < / ___ \| |\ | | | | |___ ___) |
/_/ \_\_| \_\/_/ \_\_| \_| |_| |_____|____/
Você pode criar seu próprio banner nesse link
install_packages.yml
Task para instalar os pacotes que eu definir na variável vars/main.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- name: Remove apt lock file
vars:
my_var: ""
file:
path: ""
state: absent
with_items:
- "/var/lib/dpkg/lock"
- "/var/lib/dpkg/lock-frontend"
loop_control:
loop_var: lock_file
- name: dpkg configure
command: dpkg --configure -a
- name: APT | Installing Linux Apps
ansible.builtin.apt:
name: ''
state: latest
ssh.yml
Task para configurar o serviço de SSH:
1
2
3
4
5
6
7
8
9
10
11
12
13
- name: SSH | Disable password authentication for root
lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin prohibit-password'
- name: SSH | Disable tunneled clear-text passwords
lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^PasswordAuthentication yes'
line: 'PasswordAuthentication no'
upgrade.yml
Task para atualizar todos os pacotes e sistema operacional:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- name: APT | Upgrade dist
ansible.builtin.apt:
upgrade: yes
update_cache: yes
- name: LINUX | Check if a reboot is required.
ansible.builtin.stat:
path: /var/run/reboot-required
get_checksum: no
register: reboot_required_file
- name: LINUX | Reboot the server (if required).
ansible.builtin.reboot:
when: reboot_required_file.stat.exists == true
- name: APT | Remove dependencies that are no longer required.
ansible.builtin.apt:
autoremove: yes
vars/main.yml
Arquivo de variáveis para esta role com os pacotes que será instalado:
1
2
3
4
5
6
7
8
9
10
11
---
# vars file for config-vm-linux
packages:
- vim
- curl
- wget
- htop
- apt-transport-https
- ca-certificates
- git
- unzip
Com os scripts acima, a máquina estará com uma configuração “básica/inicial” que eu acho pertinente para o meu homelab, sintam-se livre para editar ou remover algum item.
Executar a playbook do Ansible
Se você seguir a estrutura de pastas e arquivos que eu fiz, você precisará estar na raiz, onde se encontra o arquivo de hosts do Ansilbe e o arquivo main.yml, executar o comando passando na variável vm_name o nome da máquina virtual que quer criar, no exemplo abaixo a máquina virtual terá o nome de lnx-teste-01:
1
ansible-playbook main.yml --extra-vars vm_name="lnx-teste-01"
A playbook se executada com sucesso, trará o resultado abaixo, lembrando que 192.168.1.250 é meu servidor proxmox:
E também é enviado uma mensagem no Telegram, pois eu geralmente executo a playbook e vou fazer outra coisa 😊 😜:
A segunda parte é a role para configurar o servidor linux e traz o seguinte resultado se executada com sucesso:
Pessoal eu separei para trazer os prints, vocês podem e eu faço isso, executar tudo de uma vez!
Concluindo!
Isso tudo poderia ser feito manualmente ou até pelo portal web do Proxmox, mas usar o Ansible me força a estudar e aprender cada vez mais essa tecnologia, e como o Ansible não faz parte do meu dia a dia atualmente sempre encontro desafios, mas é algo que quero estar com o conhecimento afiado!
Bom pessoal, espero que tenha gostado e que esse artigo seja útil a vocês!
Artigos relacionados
Compartilhe o artigo com seus amigos clicando nos icones abaixo!!!