Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add example for running rolling update #18

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions examples/inventory-rolling-update/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 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, you will need:

- Terraform
- Ansible
- upcloud-ansible-collection and UpCloud python SDK (`upcloud-api>=2.5.0`)

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 prompted by Terraform to accept the plan
```

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 tag (cow, dog, hello, or tiger) to use
ansible-playbook configure-webserver.yml --extra-vars "animal=tiger"
```

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/UpCloudLtd/hello-container/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/UpCloudLtd/hello-container/releases/download/{{ release.json.tag_name }}/hello-{{ animal }}.tar.gz
dest: /usr/share/nginx/html/
notify:
- Restart nginx
- name: Configure nginx
get_url:
url: https://github.com/UpCloudLtd/hello-container/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
}
Loading