Skip to content

Instantly share code, notes, and snippets.

@brmzkw
Last active October 2, 2021 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brmzkw/d1c690dc3f1167093f931681b1129959 to your computer and use it in GitHub Desktop.
Save brmzkw/d1c690dc3f1167093f931681b1129959 to your computer and use it in GitHub Desktop.
"""This snippet uses Scaleway APIs to:
- Create a PostgreSQL database
- Create a S3 bucket
- Create one loadbalancer
- Create 3 instances and install nginx with cloud-init
- Attach instances to the loadbalancer
Install dependencies with `pip install boto3 requests`.
Before running this script, get your organization id and authentication token from the console (https://console.scaleway.com/) and:
$> export SCW_ORGANIZATION=xxx
$> export SCW_AUTH_TOKEN=xxx
"""
#!/usr/bin/env python
import os
import random
import sys
import time
import boto3
import requests
import uuid
def database_create(organization, auth_token):
username = 'demo'
# Append 'XX' because password needs to contain at least one uppercase letter
password = str(uuid.uuid4()) + 'XX'
payload = {
'name': 'mydatabase',
'engine': 'PostgreSQL-11',
'tags': ['demo'],
'is_ha_cluster': True,
'disable_backup': False,
'user_name': username,
'password': password,
'node_type': 'db-beta',
'organization_id': organization,
}
resp = requests.post(
'https://api-world.scaleway.com/rdb/v1alpha1/regions/fr-par/instances',
json=payload,
headers={'X-Auth-Token': auth_token}
)
print('Database id: %s (username: %s - password: %s)' % (resp.json()['id'], username, password))
return resp.json()
def loadbalancer_create(organization, auth_token):
payload = {
'description': 'Demo load balancer',
'name': 'myloadbalancer',
'organization_id': organization,
'tags': ['demo']
}
resp = requests.post(
'https://api.scaleway.com/lb/v1/regions/fr-par/lbs',
json=payload,
headers={'X-Auth-Token': auth_token}
)
print('Loadbalancer id: %s' % resp.json()['id'])
return resp.json()
def s3_create_bucket(secret_key):
# Retrieve access key
resp = requests.get('https://account.scaleway.com/tokens/%s' % secret_key)
access_key = resp.json()['token']['access_key']
s3 = boto3.resource(
's3',
region_name='fr-par',
endpoint_url='http://s3.fr-par.scw.cloud',
aws_access_key_id=access_key,
aws_secret_access_key=secret_key
)
# Add random number after bucket since the name must be globally unique
bucket_name = 'demo-%s' % random.randint(0, 10000)
s3.create_bucket(Bucket=bucket_name)
print('Bucket name: %s' % bucket_name)
def instance_create(organization, auth_token, name='demo'):
# Get image id
resp = requests.get('https://api-marketplace.scaleway.com/images?arch=x86_64&only_current=true&category=distribution')
for image in resp.json()['images']:
if image['name'].lower() == 'ubuntu bionic':
break
else:
raise RuntimeError('Ubuntu Bionic not found')
version = image['versions'][0]
for local_image in version['local_images']:
if local_image['arch'] == 'x86_64' and local_image['zone'] == 'par1':
break
else:
raise RuntimeError('Image for Ubuntu Bionic not found in Paris')
# Create IP address for the instance
payload = {
'organization': organization
}
resp = requests.post(
'https://cp-par1.scaleway.com/ips',
json=payload,
headers={'X-Auth-Token': auth_token}
)
ip_id = resp.json()['ip']['id']
print('IP address created: %s' % ip_id)
payload = {
'name': name,
'dynamic_ip_required': False,
'commercial_type': 'DEV1-S',
'boot_type': 'local',
'enable_ipv6': True,
'volumes': {
'0': {
'size': 20000000000
}
},
'image': local_image['id'],
'public_ip': ip_id,
'organization': organization
}
resp = requests.post(
'https://cp-par1.scaleway.com/servers/',
json=payload,
headers={'X-Auth-Token': auth_token}
)
server_id = resp.json()['server']['id']
print('Instance created: %s' % server_id)
# Change cloud-init configuration to install nginx
requests.patch(
'https://cp-par1.scaleway.com/servers/%s/user_data/cloud-init' % server_id,
data='''#cloud-config
packages:
- nginx
''',
headers={'Content-Type': 'text/plain', 'X-Auth-Token': auth_token}
)
## Start server
payload = {'action': 'poweron'}
requests.post(
'https://cp-par1.scaleway.com/servers/%s/action' % server_id,
json=payload,
headers={'X-Auth-Token': auth_token}
)
return resp.json()['server']
def loadbalancer_attach_server(loadbalancer, server, auth_token):
# Wait until server is on, otherwise we can't link the server to the loadbalancer
print('Wait until server %s is on to create lb...' % server['id'])
while True:
server = requests.get(
'https://cp-par1.scaleway.com/servers/%s' % server['id'],
headers={'X-Auth-Token': auth_token}
).json()['server']
if server['private_ip']:
break
time.sleep(5)
print('...')
# List existing backends
resp = requests.get(
'https://api-world.scaleway.com/lb/v1/regions/fr-par/lbs/%s/backends' % loadbalancer['id'],
headers={'X-Auth-Token': auth_token}
)
# Get or create two backends for ports 80 and 443
backends = resp.json()['backends']
for name, port in (('http', 80), ('https', 443)):
for backend in backends:
if backend['name'] == name:
break
# Does not exist, create it
else:
payload = {
'forward_protocol': 'tcp',
'forward_port': port,
'send_proxy_v2': False,
'server_ip': [],
'health_check': {
'check_delay': 1001,
'check_max_retries': 3,
'check_timeout': 3000,
'port': port,
'tcp_config': {}
},
'sticky_sessions': 'none',
'name': name,
}
resp = requests.post(
'https://api-world.scaleway.com/lb/v1/regions/fr-par/lbs/%s/backends' % loadbalancer['id'],
json=payload,
headers={'X-Auth-Token': auth_token}
)
backend = resp.json()
print('Created loadbalancer backend %s with id: %s' % (name, backend['id']))
# Create the frontend
payload = {
'inbound_port': port,
'name': 'frontend-%s' % name,
'backend_id': backend['id']
}
resp = requests.post(
'https://api-world.scaleway.com/lb/v1/regions/fr-par/lbs/%s/frontends' % loadbalancer['id'],
json=payload,
headers={'X-Auth-Token': auth_token}
)
print('Created loadbalancer frontend %s with id: %s' % ('frontend-%s' % name, resp.json()['id']))
payload = {
'server_ip': [server['private_ip']]
}
resp = requests.post(
'https://api-world.scaleway.com/lb/v1/regions/fr-par/backends/%s/servers' % backend['id'],
json=payload,
headers={'X-Auth-Token': auth_token}
)
def main():
envvars = {}
for envvar in ('SCW_AUTH_TOKEN', 'SCW_ORGANIZATION'):
value = os.getenv(envvar)
if not value:
sys.stderr.write('%s environment variable required\n' % envvar)
sys.exit(1)
envvars[envvar] = value
database_create(envvars['SCW_ORGANIZATION'], envvars['SCW_AUTH_TOKEN'])
lb = loadbalancer_create(envvars['SCW_ORGANIZATION'], envvars['SCW_AUTH_TOKEN'])
s3_create_bucket(envvars['SCW_AUTH_TOKEN'])
for idx in range(1, 4):
server = instance_create(envvars['SCW_ORGANIZATION'], envvars['SCW_AUTH_TOKEN'], name='demo-%s' % idx)
loadbalancer_attach_server(lb, server, envvars['SCW_AUTH_TOKEN'])
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment