Skip to content
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
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,55 @@ raptor import project-type --managed facets/azure --name "My Platform"

---

### Linode (Akamai) — Preview

LKE (Linode Kubernetes Engine) clusters with node pools, Linode VPC networking, S3-compatible object storage, managed PostgreSQL, and a cloud-agnostic Kubernetes service — plus the shared K8s platform and KubeBlocks datastores.

**First, create a Linode API token** at https://cloud.linode.com/profile/tokens with read/write on Linodes, Kubernetes, VPCs, IPs, Object Storage, and Databases. Full walkthrough: [`project-type/linode/ONBOARDING.md`](project-type/linode/ONBOARDING.md).

**Prompt for Praxis:**

```
Import the Linode project type for me from the facets-modules-redesign repo
(project-type/linode/project-type.yml) along with its output types.
```

**Raptor CLI:** (imports the project type + modules + outputs; no base template — projects start empty)

```bash
raptor import project-type -f ./project-type/linode/project-type.yml \
--modules-dir ./modules --outputs-dir ./outputs
```

With custom name:

```bash
raptor import project-type -f ./project-type/linode/project-type.yml \
--modules-dir ./modules --outputs-dir ./outputs --name "Linode Platform"
```

<details>
<summary><strong>What's included</strong></summary>

**Infrastructure**
`Cloud Account (linode_provider)` `Network/VPC (linode_vpc)` `LKE Cluster (lke)` `Node Pool (lke)` `Object Storage (linode)` `Service (k8s)`

**Managed Datastores**
`PostgreSQL (linode)`

**Self-hosted via KubeBlocks**
`PostgreSQL` `MySQL` `MongoDB` `Redis`

**K8s Platform**
`Helm` `Ingress/NGINX` `cert-manager` `ConfigMap` `Secrets` `PVC` `Access Controls` `Callbacks` `K8s Resources` `Gateway API CRD` `Artifactories`

**Operators & Monitoring**
`KubeBlocks` `ECK` `Prometheus` `Grafana` `Alert Rules` `Monitoring`

</details>

---

## Links

- [Facets Control Plane](https://facets.cloud)
Expand Down
31 changes: 31 additions & 0 deletions modules/cloud_account/linode_provider/1.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Linode (Akamai) Provider Configuration

Configures the Linode Terraform provider with API token authentication for use by other Linode modules.

## Overview

This module establishes the foundational Linode (Akamai Cloud) provider configuration using a Linode Personal Access Token (PAT). It serves as the base provider configuration that other Linode infrastructure modules (VPC, LKE, Object Storage, Managed Database) consume to access Linode APIs and provision resources. It produces the `@facets/linode_cloud_account` output type.

## Environment as Dimension

**Environment-specific provider configuration**: The API token is a secret reference and the default region is an override-only field, allowing different Linode credentials and regions per environment.

## Resources Created

- **Linode Provider Configuration**: Establishes an authenticated connection to the Linode API
- **Provider Output Interface**: Exposes the configured provider and default region for consumption by other modules

## Security Considerations

- The API token is supplied via a secret reference and is never stored in plain text within the module configuration
- The token is declared in the `secrets` output attribute so the platform treats it as sensitive
- Provider configuration is scoped per environment for security isolation

## Required Configuration

- **Linode API Token**: A Linode Personal Access Token with read/write scopes (secret reference)
- **Linode Region**: The default region for downstream resources, e.g. `us-east`, `us-ord`, `eu-west`, `ap-south` (override-only)

## Usage Notes

This module does not create any actual Linode resources — it only configures the provider authentication. Other Linode modules should consume this module's `@facets/linode_cloud_account` output to access Linode services with proper authentication.
54 changes: 54 additions & 0 deletions modules/cloud_account/linode_provider/1.0/facets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
intent: cloud_account
flavor: linode_provider
version: "1.0"
description: Module to configure and provision resources within a Linode (Akamai) cloud account
intentDetails:
type: Cloud & Infrastructure
description: Configure and provision resources within a Linode (Akamai) cloud account
displayName: Cloud Account
iconUrl: https://raw.githubusercontent.com/Facets-cloud/facets-modules-redesign/main/icons/cloud_account.svg
clouds:
- kubernetes
spec:
title: Linode Provider Configuration
description: Configure Linode (Akamai) API access credentials and the default region
type: object
properties:
token:
type: string
title: Linode API Token
description: Linode Personal Access Token with read/write scopes for the resources you intend to manage
x-ui-secret-ref: true
region:
type: string
title: Linode Region
description: Default Linode region for downstream resources (e.g. us-east, us-ord, eu-west, ap-south)
x-ui-placeholder: us-east
x-ui-overrides-only: true
required:
- token
- region
x-ui-order:
- token
- region
outputs:
default:
type: "@facets/linode_cloud_account"
providers:
linode:
source: linode/linode
version: 3.13.0
attributes:
token: attributes.token
sample:
kind: cloud_account
flavor: linode_provider
version: "1.0"
disabled: true
spec:
token: ""
region: us-east
iac:
validated_files:
- main.tf
- variables.tf
4 changes: 4 additions & 0 deletions modules/cloud_account/linode_provider/1.0/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Linode (Akamai) Provider Configuration Module
# This module configures the Linode provider credentials and exposes them for other modules.
#
# Note: output_attributes and output_interfaces locals are defined in outputs.tf
9 changes: 9 additions & 0 deletions modules/cloud_account/linode_provider/1.0/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
locals {
output_attributes = {
token = var.instance.spec.token
region = var.instance.spec.region
secrets = "[\"token\"]"
}
output_interfaces = {
}
}
31 changes: 31 additions & 0 deletions modules/cloud_account/linode_provider/1.0/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
variable "instance" {
description = "Configures the Linode (Akamai) Terraform provider with API token authentication"
type = object({
kind = string
flavor = string
version = string
spec = object({
token = string
region = string
})
})
}

variable "instance_name" {
description = "The architectural name for the resource as added in the Facets blueprint designer."
type = string
}

variable "environment" {
description = "An object containing details about the environment."
type = object({
name = string
unique_name = string
})
}

variable "inputs" {
description = "A map of inputs requested by the module developer."
type = object({
})
}
26 changes: 26 additions & 0 deletions modules/datastore/postgres/linode/1.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Linode Managed PostgreSQL

Creates a Linode (Akamai) managed PostgreSQL database using the v2 API. Produces the `@facets/postgres` output type (reader/writer connection interfaces).

## Overview

Provisions a managed PostgreSQL cluster (single node or 3-node HA). Connection details are exposed via the standard `@facets/postgres` reader and writer interfaces, making the database swappable with PostgreSQL modules on other clouds. SSL is required on connections.

## Resources Created

- **linode_database_postgresql_v2**: The managed PostgreSQL cluster (`prevent_destroy` enabled)

## Required Configuration

- **Version**: PostgreSQL major version (13–16)
- **Type**: Linode instance type (e.g. `g6-nanode-1`)
- **Cluster Size**: `1` (single) or `3` (HA)
- **Allowed CIDRs** (optional): IP allow-list for client access (empty denies external access — populate with your LKE node egress CIDRs to connect)

## Inputs

- **Linode Cloud Account** (`@facets/linode_cloud_account`): provides the Linode provider and region

## Outputs

- `@facets/postgres`: `writer` and `reader` interfaces with `host`, `port`, `username`, `password`, `connection_string`
114 changes: 114 additions & 0 deletions modules/datastore/postgres/linode/1.0/facets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
intent: postgres
flavor: linode
version: "1.0"
clouds:
- kubernetes
description: Managed PostgreSQL database on Linode (Akamai) with SSL/TLS and IP allow-listing
intentDetails:
type: Datastores
description: Linode (Akamai) managed PostgreSQL database service
displayName: PostgreSQL
iconUrl: https://raw.githubusercontent.com/Facets-cloud/facets-modules-redesign/main/icons/postgres.svg
spec:
title: Linode Managed PostgreSQL Database
description: Managed PostgreSQL database on Linode (Akamai)
type: object
x-ui-order:
- version_config
- sizing
- network_access
properties:
version_config:
type: object
title: Version Configuration
x-ui-order:
- version
properties:
version:
type: string
title: PostgreSQL Version
description: PostgreSQL engine major version
enum:
- "13"
- "14"
- "15"
- "16"
default: "16"
required:
- version
sizing:
type: object
title: Sizing & Performance
x-ui-order:
- type
- cluster_size
properties:
type:
type: string
title: Instance Type
description: Linode instance type for database nodes
enum:
- g6-nanode-1
- g6-standard-1
- g6-standard-2
- g6-dedicated-2
- g6-dedicated-4
default: g6-nanode-1
cluster_size:
type: integer
title: Cluster Size
description: Number of nodes (1 = single node, 3 = high availability)
enum:
- 1
- 3
default: 1
required:
- type
- cluster_size
network_access:
type: object
title: Network Access
properties:
allow_list:
type: array
title: Allowed CIDRs
description: List of CIDRs permitted to connect (empty denies all external access)
default: []
items:
type: string
pattern: ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$
required: []
required:
- version_config
- sizing
inputs:
linode_cloud_account:
type: "@facets/linode_cloud_account"
optional: false
displayName: Linode Cloud Account
description: Linode provider configuration and default region
providers:
- linode
outputs:
default:
type: "@facets/postgres"
title: Linode PostgreSQL Database
sample:
kind: postgres
flavor: linode
version: "1.0"
disabled: true
spec:
version_config:
version: "16"
sizing:
type: g6-nanode-1
cluster_size: 1
network_access:
allow_list: []
iac:
validated_files:
- main.tf
- variables.tf
- outputs.tf
- versions.tf
28 changes: 28 additions & 0 deletions modules/datastore/postgres/linode/1.0/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Linode Managed PostgreSQL Module
# Creates a Linode managed PostgreSQL database (v2 API).

module "name" {
source = "github.com/Facets-cloud/facets-utility-modules//name"
environment = var.environment
limit = 32
resource_name = var.instance_name
resource_type = "postgres"
}

locals {
region = var.inputs.linode_cloud_account.attributes.region
engine_id = "postgresql/${var.instance.spec.version_config.version}"
}

resource "linode_database_postgresql_v2" "db" {
label = module.name.name
engine_id = local.engine_id
region = local.region
type = var.instance.spec.sizing.type
cluster_size = var.instance.spec.sizing.cluster_size
allow_list = var.instance.spec.network_access.allow_list

lifecycle {
prevent_destroy = true
}
}
30 changes: 30 additions & 0 deletions modules/datastore/postgres/linode/1.0/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
locals {
# The v2 managed-database API exposes a single primary host; read scaling is handled
# by the platform, so reader and writer share the primary endpoint.
writer_host = linode_database_postgresql_v2.db.host_primary
reader_host = linode_database_postgresql_v2.db.host_primary
db_port = tostring(linode_database_postgresql_v2.db.port)
db_user = linode_database_postgresql_v2.db.root_username
db_password = linode_database_postgresql_v2.db.root_password

output_attributes = {}

output_interfaces = {
writer = {
host = local.writer_host
port = local.db_port
username = local.db_user
password = local.db_password
connection_string = "postgresql://${local.db_user}:${local.db_password}@${local.writer_host}:${local.db_port}/defaultdb?sslmode=require"
secrets = ["password", "connection_string"]
}
reader = {
host = local.reader_host
port = local.db_port
username = local.db_user
password = local.db_password
connection_string = "postgresql://${local.db_user}:${local.db_password}@${local.reader_host}:${local.db_port}/defaultdb?sslmode=require"
secrets = ["password", "connection_string"]
}
}
}
Loading