Week 11 Lab 3: Declarative Infrastructure with Heat
Module: Operating Systems 3 (Virtualisation & Cloud Technologies)
Estimated Time: 45 Minutes
Lab Type: YAML / Orchestration
Lab Overview
In Lab 1, you wrote a Bash script to launch a server. In Lab 2, you used Ansible to configure it. Now, we will replace the Imperative Bash script with a Declarative Heat Template.
The Difference:
- Bash: "Run this command, then run that command." (If you run it twice, it breaks).
- Heat: "Here is the final state I want." (If you run it twice, it does nothing because the state is already reached).
Objectives:
1. Write a Template: Create a deployment.yaml file describing the network, security group, and server.
2. Deploy a Stack: Use openstack stack create.
3. Update a Stack: Change the configuration and watch Heat apply only the delta.
4. Clean Up: Delete the entire environment with one command.
Prerequisites:
- MicroStack running.
jqtool installed.
Part 1: Writing the Template
-
Create the file:
bash nano deployment.yaml -
Add the Infrastructure Definition: We will define a Network, a Security Group allowing SSH/HTTP, and a Server.
heat_template_version: 2018-08-31
description: Lab 3 Declarative Stack
parameters:
key_name:
type: string
default: lab-key
description: Name of the keypair to use
image_name:
type: string
default: ubuntu
public_net:
type: string
default: external
resources:
# 1. The Network
app_net:
type: OS::Neutron::Net
app_subnet:
type: OS::Neutron::Subnet
properties:
network: { get_resource: app_net }
cidr: 192.168.20.0/24 # Different subnet from Lab 1
headers:
- { get_param: public_net }
# 2. The Security Group
web_sg:
type: OS::Neutron::SecurityGroup
properties:
description: "Allow SSH and HTTP"
rules:
- protocol: tcp
port_range_min: 22
port_range_max: 22
remote_ip_prefix: 0.0.0.0/0
- protocol: tcp
port_range_min: 80
port_range_max: 80
remote_ip_prefix: 0.0.0.0/0
# 3. The Server
web_instance:
type: OS::Nova::Server
properties:
name: heat-web-01
image: { get_param: image_name }
flavor: m1.tiny
key_name: { get_param: key_name }
networks:
- network: { get_resource: app_net }
security_groups:
- { get_resource: web_sg }
user_data: |
#cloud-config
packages:
- nginx # Note: Standardizing on Nginx for this lab
runcmd:
- systemctl start nginx
# 4. Floating IP
my_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network: { get_param: public_net }
# 5. Connect IP to Server
association:
type: OS::Neutron::FloatingIPAssociation
properties:
floatingip_id: { get_resource: my_ip }
port_id: { get_attr: [web_instance, addresses, { get_resource: app_net }, 0, port] }
outputs:
website_url:
description: The public IP
value: { get_attr: [my_ip, floating_ip_address] }
- Validate syntax:
Before deploying, check for typos.
bash openstack orchestration template validate -t deployment.yamlIf this returns JSON output, your YAML is valid.
Part 2: Deploying the Stack
-
Create the Stack:
bash openstack stack create -t deployment.yaml --wait lab3-stack-t: The template file.--wait: Blocks the terminal until the deployment is finished.
-
Verify: Once it finishes, check the output to see the IP address.
bash openstack stack show lab3-stackLook for theoutputssection at the bottom. -
Test the Server: Open the IP address in your browser. You should see "Welcome to nginx!".
-
Field Report:
- Stack Status:
[ ___________________ ](Should be CREATE_COMPLETE) - Floating IP:
[ ___________________ ]
- Stack Status:
Part 3: The Power of Updates (Declarative)
This is the most important part of the lab. We will change the requirements and ask Heat to fix it.
-
Scenario: Your security manager wants you to block SSH (Port 22) and only allow HTTP.
-
Edit the Template: Open
deployment.yaml.- Locate the
web_sgresource. - DELETE the rule block for port 22.
- Save the file.
- Locate the
-
Update the Stack: Run the same command, but with
update.bash openstack stack update -t deployment.yaml --wait lab3-stackObservation: * Did Heat verify everything? Yes. * Did it destroy the server? No. * Did it change the IP? No. * It only removed the security group rule. This is Idempotency.
-
Verify: Try to SSH into the server using the IP from earlier.
bash ssh ubuntu@<IP>- Result: It should Hang/Timeout (because the rule is gone).
- Website: It should still work.
Part 4: Cleanup
In Lab 1, cleaning up the script's mess required finding the Instance ID, Floating IP ID, and Security Group ID separately. With Heat, we treat the stack as a single unit.
-
Delete the Stack:
bash openstack stack delete -y lab3-stack -
Verify:
bash openstack server list openstack app_net listEverything defined in the template is gone.
Lab Checkpoint
- I have written a valid Heat Template.
- I have successfully deployed a stack (Server + Net + SG + IP).
- I have demonstrated a Stack Update by modifying the Security Group.
Reflection:
- Why is
stack updatesafer than manually running commands on a production server? - If we deleted the server manually (
openstack server delete) but kept the stack, what would happen if we ranstack update? (Hint: Heat would notice the server is missing and recreate it—this is called Self-Healing).
Instructor Signature: ___ Date: ___