webservice_scaleset
Description
This example creates a load balanced https web farm using a scaleset to dynamically resize the number of virtual machines running nginx. The front end of the balancer listens to ports 80 and 443, and creates the necessary structures to store and use a certificate (it can be self-signed).
Due to the fundamental differences in networking between AWS (which uses subnets that are in availability zones) and Azure (which uses subnets that are region-wide), a portable blueprint creates one subnet per availability zone for the virtual machine traffic. On AWS all of the subnets may be used, however on Azure only one of the subnets will be used.
To make the example portable, use a 2048-bit length private key. If you use a larger length private key on AWS you will receive a "certificate not found" error, which is due to an AWS configuration limitation of ELBv2 load balancers against ACM.
Concepts
The following concepts are present in this example:
Certificates
HTTPS
Linux
Load Balancing
Nginx
Scalesets
Secrets
Userdata
Variables
Virtual Machines
Venues
This example is regularly tested against:

Release Notes
1.0
Initial release.
2.0
Added variables for controlling vm, zone counts.
Added https support for existing certificates.
3.0
Removed the prerequisite for certificates (and on Azure, a managed identity) to be created manually before applying this example.
Added support for importing certificates into the venue.
Removed azure-specific variables.
4.0
Converted to using a scaleset.
Blueprint
---
variables:
admin_username:
description: >-
The administrative username for SSH access to the linux virtual machines.
Note that the web servers are not publicly accessible however they still
require an administrative user configuration.
type: string
default: adminuser
admin_public_key:
description: >-
The administrative public key for SSH access to the linux virtual machines.
Note that the web servers are not publicly accessible however they still
require an administrative user configuration.
type: string
balancer_cert_body:
description: >-
The balancer certificate in PEM format.
type: string
balancer_cert_private_key:
description: >-
The balancer certificate's private key in PEM format.
type: secret
location:
region:
my-region:
country: USA
area: northwest
folder:
tuono-webservice-vmss:
region: my-region
security:
certificate:
webservice-cert:
body: (( balancer_cert_body ))
private_key: (( balancer_cert_private_key ))
networking:
network:
webservice:
range: 10.0.0.0/16
scope: public
balancer:
webservice-balancer:
network: webservice
scope: public
purpose: testing
routes:
# redirect port 80 to port 443
- from: external-http
to: external-https
# service port 443
- from: external-https
to: internal-http-dev
service:
external-http:
# traffic coming in from the internet
port: 80
protocol: http
external-https:
# secure traffic coming in from the internet
port: 443
protocol: https
certificate: webservice-cert
security_policy:
aws: ELBSecurityPolicy-TLS-1-2-Ext-2018-06
azure: AppGwSslPolicy20170401S
internal-http-dev:
# traffic for the web service internally
port: 8080
protocol: http
compute:
image:
bitnami:
publisher: bitnami
product: nginxstack
sku: 1-9
venue:
aws:
image_id: ami-0e789678bc78bb87e
scaleset:
webpool:
monitor:
- metric: cpu
grow:
threshold: 75
duration: 2 minutes
cooldown: 10 minutes
shrink:
threshold: 25
duration: 5 minutes
cooldown: 15 minutes
network: webservice
provides: internal-http-dev
scope: private-no-internet
size:
default: 3
maximum: 4
minimum: 2
cores: 1
memory: 1 GB
image: bitnami
tags:
wicked: awesome
configure:
admin:
# required to initiate a deploy on Azure, but ignored on AWS
# when userdata is present
username: (( admin_username ))
public_key: (( admin_public_key ))
userdata:
# why not use cloud-init?
# answer: the azure bitnami nginx marketplace image has disabled cloud-init
# so we have to use a shell script to make a portable example
type: shell
content: |
#!/bin/sh
### debugging mode so we can see what is happening in the logs
set -x
### set up administrative user (idempotent)
userid=$(id -u (( admin_username )))
if [ -z "$userid" ]; then
set -e
adduser --gecos "" --disabled-password (( admin_username ))
cd ~(( admin_username ))
mkdir .ssh
chmod 700 .ssh
echo "(( admin_public_key ))" > .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
chown -R (( admin_username )).(( admin_username )) .ssh
usermod -aG sudo (( admin_username ))
echo "(( admin_username )) ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
set +e
fi
### set up nginx by replacing the home page
echo "webserver-$(uuidgen)" > /opt/bitnami/nginx/html/index.html
### make it run on port 8080
sed -i 's/listen 80;/listen 8080;/' /opt/bitnami/nginx/conf/nginx.conf
### restart nginx due to the port change
/opt/bitnami/ctlscript.sh restart nginx
Last updated
Was this helpful?