Creating an instance with Ansible
This tutorial shows how to create an instance and run an nginx web server on Breqwatr Cloud using Ansible.
Prerequisites
- Python 3 and
pipon your Ansible host. - Ansible installed (see Install Ansible below).
- The
openstack.cloudAnsible collection (installed below). - The Ansible host connected to the same internal network as the instance it will deploy. The host's public key is used as the key pair injected into the new instance.
Create a virtual environment (Recommended)
Install Ansible
You can use your Linux distribution's package manager:
Or use pip on any operating system:
Install the openstack.cloud collection
Place a clouds.yaml file
Ansible's openstack.cloud collection reads credentials from
clouds.yaml. Don't hand-roll one — download a ready-made file
from the Portal's
Application credentials
page (the same file works for Ansible, Terraform, and the
OpenStack CLI). Move it to either of:
- A working directory next to your playbooks (the collection picks it up from the current dir).
- The shared user location at
~/.config/openstack/clouds.yaml(or%APPDATA%\openstack\clouds.yamlon Windows) so every tool that readsclouds.yamlshares one file.
The downloaded entry is named breqwatr. Tell the openstack.cloud
modules which entry to use by setting OS_CLOUD once in your
shell:
or by passing cloud: breqwatr on every module call (the modules
support both).
Steps
1. Create the playbooks
The following playbook create-server.yaml will create:
- A security group for HTTP and one for SSH
- Matching ingress rules
- A
v1.c1r4instance
---
- name: Create a new instance and attach it to a network
hosts: localhost
connection: local
gather_facts: false
vars:
# Server variables
server_name: test-ansible
image_id: 533cf45e-7284-4594-84a7-13d64065b7d2
flavor_name: v1.c1r4
keypair_name: ansible
volume_size_gb: 20
network_name: cloud-docs-net
# Security groups
sg_ssh: ssh-ansible
sg_http: http-hello-world
tasks:
- name: Create SSH security group
openstack.cloud.security_group:
state: present
name: "{{ sg_ssh }}"
description: Security group for SSH
- name: Create SSH security group rule
openstack.cloud.security_group_rule:
security_group: "{{ sg_ssh }}"
protocol: tcp
port_range_min: 22
port_range_max: 22
remote_ip_prefix: 0.0.0.0/0
- name: Create HTTP security group
openstack.cloud.security_group:
state: present
name: "{{ sg_http }}"
description: Security group for HTTP
- name: Create HTTP security group rule
openstack.cloud.security_group_rule:
security_group: "{{ sg_http }}"
protocol: tcp
port_range_min: 80
port_range_max: 80
remote_ip_prefix: 0.0.0.0/0
- name: Create the server
openstack.cloud.server:
state: present
name: "{{ server_name }}"
image: "{{ image_id }}"
key_name: "{{ keypair_name }}"
flavor: "{{ flavor_name }}"
timeout: 200
nics:
- net-name: "{{ network_name }}"
security_groups:
- "{{ sg_http }}"
- "{{ sg_ssh }}"
- default
boot_from_volume: true
volume_size: "{{ volume_size_gb }}"
auto_ip: false
- name: Get server information
openstack.cloud.server_info:
server: "{{ server_name }}"
register: server_info
- name: Extract private IP address
set_fact:
private_ip: "{{ server_info.servers[0].addresses[network_name][0].addr }}"
- name: Display server IP address
debug:
msg: "Server {{ server_name }} private IP: {{ private_ip }}"
For installing nginx, create install-nginx.yaml:
---
- name: Install and configure nginx
hosts: test-ansible
become: true
tasks:
- name: Install nginx
ansible.builtin.dnf:
name: nginx
state: present
update_cache: yes
- name: Enable and start nginx
ansible.builtin.systemd:
name: nginx
state: started
enabled: true
- name: Create test index page
ansible.builtin.copy:
dest: /usr/share/nginx/html/index.html
content: "<h1>Nginx is working</h1>"
For cleanup, create cleanup.yaml:
---
- name: Clean up server and security groups
hosts: localhost
connection: local
vars:
# Resources to delete
server_name: "test-ansible"
security_groups:
- "http-hello-world"
- "ssh-ansible"
tasks:
- name: Remove server (if present)
openstack.cloud.server:
name: "{{ server_name }}"
state: absent
- name: Remove security groups (if present)
openstack.cloud.security_group:
name: "{{ item }}"
state: absent
loop: "{{ security_groups }}"
2. Run the create-server playbook
This will create the instance and output its IP address. Copy the IP and create an inventory file:
Note: The ansible_user depends on the Linux distribution cloud image you deploy.
Replace <ip-address> with the IP of your instance and save the file.
3. Install nginx on the instance
Verification
Type the IP address of your instance into your browser. You should see the Nginx test page titled "Nginx is working".
Cleanup
To remove the instance and the security groups you just created:
This removes the security groups http-hello-world and ssh-ansible, and any instance in your project named test-ansible.
Next steps
- Launch instances via the Portal if you prefer a UI flow.
- Deploy with Terraform for the HCL-based IaC alternative.
- Application credentials to rotate or revoke the credential Ansible is using.