Last active
October 2, 2021 13:24
-
-
Save brmzkw/d1c690dc3f1167093f931681b1129959 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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