Skip to content

Commit

Permalink
chore: add example for running rolling update
Browse files Browse the repository at this point in the history
  • Loading branch information
kangasta committed Oct 4, 2023
1 parent bb41b20 commit 08c3074
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 0 deletions.
34 changes: 34 additions & 0 deletions examples/inventory-rolling-update/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Rolling update to targets from inventory plugin

This example runs a rolling update to set of servers. The servers are defined in a Terraform configuration in [resources](./resources) directory and used as target nodes via `server_group` option of the inventory plugin.

To run this example, first configure your credentials to UpCloud Terraform provider and Ansible inventory plugin by setting `UPCLOUD_USERNAME` and `UPCLOUD_PASSWORD` environment variables.

Create the servers defined in the Terraform configuration with `terraform apply` command.

```sh
terraform -chdir=resources apply
# Answer yes, when propted by Terraform
```

Configure a NGINX server with static web page by running the [configure-webserver.yml](./configure-webserver.yml) playbook.

```sh
# For initial configuration, configure all targets in parallel
ansible-playbook configure-webserver.yml --extra-vars "serial_override=0"

# When updating the targets, specify which animal (cat, cow, dog, lion, pig) to use
ansible-playbook configure-webserver.yml --extra-vars "animal=lion"
```

To monitor how the rolling update proceeds, open another terminal window and curl the load-balancer URL. The URL is visible at the output of prevous `terraform apply` command and can be printed by running `terraform output`.

```sh
watch -n 0.75 curl -s $(terraform -chdir=resources output lb_url)
```

Finally, to cleanup the created cloud resources, run `terraform destroy` in the [resources](./resources) directory.

```sh
terraform -chdir=resources destroy
```
6 changes: 6 additions & 0 deletions examples/inventory-rolling-update/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[defaults]
host_key_checking = False
inventory = ./inventory.upcloud.yml

[inventory]
enable_plugins = community.upcloud.upcloud
41 changes: 41 additions & 0 deletions examples/inventory-rolling-update/configure-webserver.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
- name: Configure webserver
hosts: all
remote_user: admin
become: yes
serial: "{{ serial_override | default(1) }}"
vars:
animal: cow
tasks:
- name: Install nginx
apt:
package: nginx
state: latest
update_cache: yes
- name: Get latest static content release
uri:
url: https://api.github.com/repos/kangasta/animals/releases/latest
register: release
- name: Remote default from enabled sites
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify:
- Restart nginx
- name: Download and unarchive static content ({{ animal }})
unarchive:
remote_src: yes
src: https://github.com/kangasta/animals/releases/download/{{ release.json.tag_name }}/animals-{{ animal }}.tar.gz
dest: /usr/share/nginx/html/
notify:
- Restart nginx
- name: Configure nginx
get_url:
url: https://github.com/kangasta/animals/releases/download/{{ release.json.tag_name }}/index.conf
dest: /etc/nginx/conf.d/
notify:
- Restart nginx
handlers:
- name: Restart nginx
service:
name: nginx
state: restarted
2 changes: 2 additions & 0 deletions examples/inventory-rolling-update/inventory.upcloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
plugin: community.upcloud.upcloud
server_group: ansible-inventory-example-servergroup
3 changes: 3 additions & 0 deletions examples/inventory-rolling-update/resources/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.terraform/
.terraform*
*.tfstate*
94 changes: 94 additions & 0 deletions examples/inventory-rolling-update/resources/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
terraform {
required_providers {
upcloud = {
source = "UpCloudLtd/upcloud"
version = "~> 2.4"
}
}
}

variable "prefix" {
type = string
default = "ansible-inventory-example-"
}

variable "zone" {
type = string
default = "pl-waw1"
}

locals {
publickey_filename = one(fileset(pathexpand("~/.ssh/"), "*.pub"))
publickey = file("~/.ssh/${local.publickey_filename}")
}

resource "upcloud_network" "network" {
name = "${var.prefix}net"
zone = var.zone

ip_network {
family = "IPv4"
address = "10.100.1.0/24"
dhcp = true
}
}

resource "upcloud_server" "webservers" {
count = 3
hostname = "${var.prefix}server-${count.index}"
title = "${var.prefix}server-${count.index}"
zone = var.zone
plan = "1xCPU-1GB"

metadata = true

login {
user = "admin"
keys = [
local.publickey,
]
}
template {
storage = "Ubuntu Server 22.04 LTS (Jammy Jellyfish)"
size = 25
title = "${var.prefix}storage-${count.index}"
}

# In production, the public interface should be (in most cases) omitted:
# - Use a jump-host in the same network to control the application nodes.
# - Use a NAT gateway to provide internet access for the application nodes.
network_interface {
type = "public"
}

network_interface {
type = "utility"
}

network_interface {
type = "private"
network = upcloud_network.network.id
}
}

resource "upcloud_server_group" "webservers" {
title = "${var.prefix}servergroup"
anti_affinity_policy = "yes"
members = upcloud_server.webservers[*].id
}

module "load_balancer" {
source = "UpCloudLtd/basic-loadbalancer/upcloud"

name = "${var.prefix}lb"
zone = var.zone
network = upcloud_network.network.id
backend_servers = [for v in upcloud_server.webservers : v.network_interface.2.ip_address]
backend_server_port = 80

frontend_port = 80
}

output "lb_url" {
value = module.load_balancer.dns_name
}

0 comments on commit 08c3074

Please sign in to comment.