Skip to content

Commit

Permalink
scaleway: initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Mathieu Tortuyaux <mtortuyaux@microsoft.com>
Co-authored-by: Kai Lüke <pothos@users.noreply.github.com>
  • Loading branch information
tormath1 and pothos committed Mar 25, 2024
1 parent 40ee7c9 commit 108fb4a
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 0 deletions.
63 changes: 63 additions & 0 deletions scaleway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Flatcar Provisioning Automation for Scaleway

This repository provides tools to automate Flatcar provisioning on [ScaleWay][scaleway] using [Terraform][terraform].

## Features

- Minimal configuration required (demo deployment works with default settings w/o any customisation, just run `terraform apply`!).
- Deploy one or multiple servers.
- Per-server custom configuration via separate [Butane][butane] configuration.

## Prerequisites

1. Scaleway credentials: `access_key`, `secret_key`, `project_id`, `organization_id`, `region` and `zone`.

## HowTo

This will create a server in 'fr-par-1' using a small instance size.
See "Customisation" below for advanced settings.

1. Clone the repo.
2. Add credentials in a `terraform.tfvars` file, expected credentials name can be found in `provider.tf`
3. Run
```shell
terraform init
```
4. Edit [`server1.yaml`][server-1] and provide your own custom provisioning configuration in [Butane][butane] syntax.
5. Plan and apply.
Invoke Terraform:
```shell
terraform plan
terraform apply
```

Terraform will print server information (name, ipv4 and v6) after deployment concluded.

_NOTE_:
* Server IP address can be found at any moment after deployment by running `terraform output`
* If you update server configuration(s) in `server-configs` and re-run `terraform apply`, the instance will be **replaced**.
Consider adding [`create_before_destroy`](https://www.terraform.io/docs/configuration/meta-arguments/lifecycle.html#syntax-and-arguments) to the `scaleway_instance_server` resource in [`compute.tf`](compute.tf) to avoid services becoming unavailable during reprovisioning.

### Customisation

The provisioning automation can be customised via settings in [`terraform.tfvars`][terraform.tfvars]:
- `cluster_name`: Descriptive name of your cluster, will be used to generate server names.
`flatcar-terraform` by default.
- `machines`: Add more machines to your deployment.
Each machine name must be unique and requires a respective `[NAME].yaml` server configuration in [`server-configs`](server-configs).
An example / default configuration for machine `server1` is provided with [`server1.yaml`](server-configs/server1.yaml).
During provisioning, server names are generated by concatenating the cluster name and the machine name - the defaults above will create a single server named `flatcar-terraform-server1`.
- `ssh_keys`: Additional SSH public keys to add to core user's `authorized_keys`.
Note that during provisioning, a provisioning RSA key pair will be generated and stored in the local directory `.ssh/provisioning_private_key.pem` and `.ssh/provisioning_key.pub`, respectively.
The private key can be used for ssh connections (`core` user) to all provisioned servers.
- `release_channel`: Select one of "lts", "stable", "beta", or "alpha".
Read more about channels [here](https://www.flatcar.org/releases).
- `flatcar_version`: Select the desired Flatcar version for the given channel (default to "current", which is the latest).
- `type`: The spec of the machine, it default to DEV1-S.
- `flatcar_file`: The local Flatcar Scaleway image to upload as a snapshot.
[butane]: https://www.flatcar.org/docs/latest/provisioning/config-transpiler/configuration/
[server-1]: server-configs/server1.yaml
[scaleway]: https://www.scaleway.com/
[terraform]: https://www.terraform.io/
[terraform-tfvars]: terraform.tfvars
53 changes: 53 additions & 0 deletions scaleway/compute.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
resource "scaleway_object_bucket" "bucket" {
name = "snapshot-flatcar-import"
}

resource "scaleway_object" "qcow" {
bucket = scaleway_object_bucket.bucket.name
key = "flatcar_production_scaleway_image.qcow2"
file = var.flatcar_file
}

resource "scaleway_instance_snapshot" "snapshot" {
type = "unified"
import {
bucket = scaleway_object.qcow.bucket
key = scaleway_object.qcow.key
}
}

resource "scaleway_instance_volume" "from_snapshot" {
from_snapshot_id = scaleway_instance_snapshot.snapshot.id
type = "b_ssd"
}

resource "scaleway_instance_server" "instance" {
for_each = toset(var.machines)
type = var.type
user_data = {
"cloud-init" = data.ct_config.machine-ignitions[each.key].rendered
}
root_volume {
volume_id = scaleway_instance_volume.from_snapshot.id
}

ip_id = scaleway_instance_ip.public_ip.id
}

data "ct_config" "machine-ignitions" {
for_each = toset(var.machines)
strict = true
content = file("${path.module}/server-configs/${each.key}.yaml")
snippets = [
data.template_file.core_user.rendered
]
}

data "template_file" "core_user" {
template = file("${path.module}/core-user.yaml.tmpl")
vars = {
ssh_keys = jsonencode(var.ssh_keys)
}
}

resource "scaleway_instance_ip" "public_ip" {}
7 changes: 7 additions & 0 deletions scaleway/core-user.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variant: flatcar
version: 1.0.0

passwd:
users:
- name: core
ssh_authorized_keys: ${ssh_keys}
20 changes: 20 additions & 0 deletions scaleway/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
output "ipv4" {
value = {
for key in var.machines :
"${var.cluster_name}-${key}" => scaleway_instance_server.instance[key].public_ip
}
}

output "ipv6" {
value = {
for key in var.machines :
"${var.cluster_name}-${key}" => scaleway_instance_server.instance[key].ipv6_address
}
}

output "name" {
value = {
for key in var.machines :
"${var.cluster_name}-${key}" => scaleway_instance_server.instance[key].name
}
}
28 changes: 28 additions & 0 deletions scaleway/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
terraform {
required_version = ">= 0.14.0"
required_providers {
scaleway = {
source = "scaleway/scaleway"
version = "2.38.2"
}
ct = {
source = "poseidon/ct"
version = "0.11.0"
}
template = {
source = "hashicorp/template"
version = "~> 2.2.0"
}
}
}

# Configure the ScaleWay Provider
provider "scaleway" {
access_key = var.access_key
secret_key = var.secret_key
project_id = var.project_id
organization_id = var.organization_id
region = var.region
zone = var.zone
}

25 changes: 25 additions & 0 deletions scaleway/server-configs/server1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
variant: flatcar
version: 1.0.0

# This is a simple NGINX example.
# Replace the below with your own config.
# Refer to https://www.flatcar.org/docs/latest/provisioning/config-transpiler/configuration/ for more information.

systemd:
units:
- name: nginx.service
enabled: true
contents: |
[Unit]
Description=NGINX example
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker rm --force nginx1
ExecStart=/usr/bin/docker run --name nginx1 --pull always --net host docker.io/nginx:1
ExecStop=/usr/bin/docker stop nginx1
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
78 changes: 78 additions & 0 deletions scaleway/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
variable "machines" {
type = list(string)
description = "Machine names, corresponding to machine-NAME.yaml.tmpl files"
default = ["server1"]
}

variable "cluster_name" {
type = string
description = "Cluster name used as prefix for the machine names"
default = "terraform-flatcar"
}

variable "ssh_keys" {
type = list(string)
default = []
description = "Additional SSH public keys for user 'core'."
}

variable "release_channel" {
type = string
description = "Release channel"
default = "stable"

validation {
condition = contains(["lts", "stable", "beta", "alpha"], var.release_channel)
error_message = "release_channel must be lts, stable, beta, or alpha."
}
}

variable "flatcar_version" {
type = string
description = "The Flatcar version associated to the release channel"
default = "current"
}

variable "region" {
type = string
description = "Scaleway region"
default = "fr-par"
}

variable "organization_id" {
type = string
description = "Scaleway organization ID"
}

variable "project_id" {
type = string
description = "Scaleway project ID"
}

variable "access_key" {
type = string
description = "Scaleway access key"
}

variable "secret_key" {
type = string
description = "Scaleway secret key"
}

variable "zone" {
type = string
description = "Scaleway zone"
default = "fr-par-1"
}

variable "type" {
type = string
description = "Scaleway instance type"
default = "DEV1-S"
}

variable "flatcar_file" {
type = string
description = "Path to the Flatcar file"
default = "./flatcar_production_scaleway_image.img"
}

0 comments on commit 108fb4a

Please sign in to comment.