Ansible Part 0.2 - Create a target host
Preparing your environment to start using Ansible
Create a Target Host with Azure VMs
Your target host is the server that you want to configure using Ansible. This tutorial creates an Azure VM as a target machine.
This can be done in a variety of ways and I have included guidance on how to do this both manually in the Azure Portal and as a bonus via using Ansible.
The Ansible Code will be run on your managed node and you will need a personal Azure Subscription with some credit in it.
SAVE CREDITS: Destroy the VM using lesson 0.4 as soon as possible after completing the tutorial to avoid incurring additional cost.
This tutorial is based on this Microsoft Guide
Dependencies
- If you are setting the VM up via Ansible you have configured your control host appropriately as per this guide
- You will need a personal Azure Subscription Microsoft Guide
- You will need a service principle for your Azure Subscription. See the tutorials here:
-
Microsoft: Create a Service Principle
- Follow the full tutorial
-
Microsoft: Store secrets for consumption by Ansible
- I recommend following option 1 and storing your credentials on the control host
-
Microsoft: Create a Service Principle
- You will need the Azure Command Line installed as part of step 4. Microsoft Guide
Tutorial - Using the Azure Portal to create the VM
Follow the below guide to create a VM in the portal.
Please use the following configuration when creating your VM:
1
2
3
4
5
6
7
8
9
10
11
Resource Group Name: learnAnsibleRG
Virtual Machine Name : myVM
Region: uksouth
Image: Ubuntu Server 24.04
Size: Standard_DS1_v2
Username: adminuser
SSH Key: SSH Public Key
Source: Generate New Key Pair
Key Name: myKey
PUBLIC IP: Make sure to have a public IP address otherwise you will not be able to connect unless your control host is in the same private network.
DOWNLOAD SSH KEY: Ensure you download the private key! Move the
.pem
file to your~/.ssh
directory
Follow this guide: Microsoft Guide to Create A VM
Tutorial - Using Ansible to Create the VM
All below commands are executed from a bash terminal.
1.
Create an SSH Key Pair on your control node
1
2
3
4
ssh-keygen -m PEM -t rsa -b 4096
# Enter the file name - default id_rsa
# Enter with NO passphrase
EXPECTED OUTPUT: you should see two files
id_rsa
andid_rsa.pub
2.
Create and update the playbook with your desired configuration
- create the playbook
1 2 3 4 5 6 7 8
mkdir ~/create_vm_ansible nano ~/create_vm_ansible/build_azure_vm.yml # Copy and Paste build_azure_vm.yml in # Replace the names with your choices # copy in the public key created in step 1 - should be saved in id_rsa.pub file in .ssh # you can also use a SED command PUBLIC_KEY=$(cat ~/.ssh/id_rsa.pub) sed -i "s|PUBLIC_KEY_DATA|$PUBLIC_KEY|g" ~/create_vm_ansible/build_azure_vm.yml
Copy in the below playbook
- Gist Code Snippet
- Copy the public key value into the
PUBLIC_KEY_DATA
placeholder. I recommend using the sed command detailed above to help.
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
---
# This playbook uses the Azure ansible modules to create a VM in Azure.
# You need to have the service principle details as per the dependencies in the tutorial
- name: Create Azure VM
hosts: localhost
connection: local
vars:
resource_group_name: learnAnsibleRG
location: uksouth
vnet_name: myVnet
subnet_name: mySubnet
public_ip_name: myPublicIP
nsg_name: myNetworkSecurityGroup
nic_name: myNIC
vm_name: myVM
vm_size: Standard_DS1_v2
vm_username: adminuser
key_data: "PUBLIC_KEY_DATA"
tasks:
- name: Create resource group
azure.azcollection.azure_rm_resourcegroup:
name: "{{ resource_group_name }}"
location: "{{ location }}"
- name: Create virtual network
azure.azcollection.azure_rm_virtualnetwork:
resource_group: "{{ resource_group_name }}"
name: "{{ vnet_name }}"
address_prefixes: "10.0.0.0/16"
- name: Add subnet
azure.azcollection.azure_rm_subnet:
resource_group: "{{ resource_group_name }}"
name: "{{ subnet_name }}"
address_prefix: "10.0.1.0/24"
virtual_network: "{{ vnet_name }}"
- name: Create public IP address
azure.azcollection.azure_rm_publicipaddress:
resource_group: "{{ resource_group_name }}"
allocation_method: Static
name: "{{ public_ip_name }}"
register: output_ip_address
- name: Public IP of VM
ansible.builtin.debug:
msg: "The public IP is {{ output_ip_address.state.ip_address }}."
- name: Create Network Security Group that allows SSH and HTTP
azure.azcollection.azure_rm_securitygroup:
resource_group: "{{ resource_group_name }}"
name: "{{ nsg_name }}"
rules:
- name: SSH
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 1001
direction: Inbound
- name: HTTP
protocol: Tcp
destination_port_range: 80
access: Allow
priority: 1002
direction: Inbound
- name: Create virtual network interface card
azure.azcollection.azure_rm_networkinterface:
resource_group: "{{ resource_group_name }}"
name: "{{ nic_name }}"
virtual_network: "{{ vnet_name }}"
subnet: "{{ subnet_name }}"
security_group: "{{ nsg_name }}"
ip_configurations:
- name: ipconfig1
public_ip_address_name: "{{ public_ip_name }}"
primary: true
- name: Create VM
azure.azcollection.azure_rm_virtualmachine:
resource_group: "{{ resource_group_name }}"
name: "{{ vm_name }}"
vm_size: "{{ vm_size }}"
admin_username: "{{ vm_username }}"
ssh_password_enabled: false
ssh_public_keys:
- path: "/home/{{ vm_username }}/.ssh/authorized_keys"
key_data: "{{ key_data }}"
network_interfaces: "{{ nic_name }}"
image:
offer: 0001-com-ubuntu-server-jammy
publisher: Canonical
sku: 22_04-lts
version: latest
- name: Public IP of VM
ansible.builtin.debug:
msg: "The public IP is {{ output_ip_address.state.ip_address }}."
The key data is sensitive and should not be committed into a repo!
3.
Run the playbook
LEARN: there is no inventory file because the commands all run on the localhost (the control node).
- Export your Azure Service Principle Credentials as Variables if you have not created a configuration file as outlined in the Dependencies.
1
2
3
4
export AZURE_SUBSCRIPTION_ID=<subscription_id>
export AZURE_CLIENT_ID=<service_principal_app_id>
export AZURE_SECRET=<service_principal_password>
export AZURE_TENANT=<service_principal_tenant_id>
2. Run the below commands on your control host
1
2
3
4
5
6
7
8
9
# Install the dependencies
ansible-galaxy collection install azure.azcollection --force
sudo pip3 install -r ~/.ansible/collections/ansible_collections/azure/azcollection/requirements.txt
# IMPORTANT: remember to have stored or exported your Azure Service Principle Credentials
# Run the playbook
ansible-playbook ~/create_vm_ansible/build_azure_vm.yml
3. Capture the output of the playbook to find the public ip address.
4.
Verify the VM exists
Execute the below commands, ensuring you update the VM name if you changed it.
1
2
3
4
5
az login
# This should open up an interactive prompt
VM_NAME=myVM
az vm list -d -o table --query "[?name=='$VM_NAME']"
5.
Test connection
From your control host attempt to SSH into the VM.
1
2
IP=<insert from output of Ansible>
ssh adminuser@$IP -i ~/.ssh/id_rsa