Module Development Guide - Innersourcing

Welcome to the Module Development Guide! This document provides resources to help you build, understand, and deploy custom modules effectively. Whether you're new to module development or looking to refine your skills, follow the steps below to get started.


📚 Tutorial: Understanding Core Concepts

Begin with our tutorial to grasp the fundamentals of module development. Learn about:

  • Module structure and best practices
  • Inputs, outputs, and variables
  • Dependency management
  • Versioning and reusability

📂 Git Repository: Detailed Documentation & Examples

Explore our Module Development GitHub Repository for:

✅ Comprehensive documentation
✅ Pre-built module templates


Quick Start: Register a Custom Module

Get started with custom modules in Facets by creating and testing a simple S3 bucket module.

Prerequisites

  • Access to a Facets Control Plane with necessary permissions
  • Terraform CLI installed (for terraform init, plan, apply)
  • Basic Terraform knowledge

Phase 1: Create and Test Your Module

1. Set Up Module Structure

First, create your module directory and the necessary files:

# Create module directory
mkdir custom_s3_module
cd custom_s3_module

# Create required files
mkdir test
touch main.tf variables.tf outputs.tf facets.yaml
touch test/test.tf test/test.json

2. Add Module Code

Copy the following Terraform configuration into your main.tf This defines the core S3 bucket resource:

resource "random_string" "bucket_suffix" {
  length  = 4
  special = false
  upper   = false
}

resource "aws_s3_bucket" "this" {
  bucket = "${var.environment.unique_name}-${var.instance_name}-${random_string.bucket_suffix.result}"
  acl    = lookup(var.instance.spec, "acl", "private")

  versioning {
    enabled = lookup(var.instance.spec, "versioning", false)
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = lookup(var.instance.spec, "sse_algorithm", "AES256")
      }
      bucket_key_enabled = false
    }
  }
}

Add these standard Facets variables to yourvariables.tf:

variable "instance" {
  description = "The JSON representation of the resource in the facets blueprint."
  type        = any
}

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

variable "environment" {
  description = "Details about the environment."
  type        = any
}

variable "inputs" {
  description = "A map of inputs requested by the module developer."
  type        = map(any)
}

Set up your outputs in outputs.tf. These values will be available for reference after deployment:

locals {
  output_interfaces = {}  # Define network interfaces if applicable
  output_attributes = {
    bucket_name = aws_s3_bucket.this.bucket
    arn         = aws_s3_bucket.this.arn
  }
}

Configure your module metadata in facets.yaml. This tells Facets how to present and use your module:

intent: s3
flavor: aws_s3_bucket
version: 1.0
clouds:
  - aws
spec:
  properties:
    bucket_name:
      type: string
      description: "Name of the S3 bucket"
    acl:
      type: string
      description: "Access control list"
      default: "private"
    environment:
      type: string
      description: "Deployment environment"
sample:
  kind: s3
  flavor: aws_s3_bucket
  metadata: {}
  disabled: true
  version: "1.0"
  spec:
    bucket_name: "example-bucket"
    acl: "private"
    environment: "prod"

3. Add Test Files

Create a sample configuration in test/test.json for local testing:

{
  "bucket_name": "example-bucket",
  "acl": "private",
  "environment": "prod"
}

Create test/test.tf to validate your module works correctly:

module "test_s3" {
  source      = "../"
  bucket_name = jsondecode(file("test.json")).bucket_name
  acl         = jsondecode(file("test.json")).acl
  environment = jsondecode(file("test.json")).environment
}

output "test_bucket_arn" {
  value = module.test_s3.bucket_arn
}

4. Test Locally

cd test
terraform init
terraform plan
terraform apply

Verify the outputs match your expectations before proceeding.

5. Register Module

You'll need three things to register your module:

  • Control Plane URL: The URL you use to access Facets (e.g.https://<your-company>.console.facets.cloud)
  • Email: Your registered email on Facets
  • Personal Token: Find this in Settings → Profile section

Your Personal Token can be found in the User menu. Click your profile icon in the bottom left, then select 'Personal Token' as shown below:

# From your module root directory
curl -s https://facets-cloud.github.io/facets-schemas/scripts/module_register.sh | bash -s -- \
  -c <control-plane-url> \
  -u <your-email> \
  -t <your-token>

6. Enable Preview Project

After registration, your module will only be available in Preview projects. This lets you safely test the module before making it available across all projects.

Your project name can be found in the Projects page of your Facets Control Plane UI, as shown below:

Run this command to enable preview mode for your project:

curl -s https://facets-cloud.github.io/facets-schemas/scripts/allow_preview_modules.sh | bash -s -- \
  -c <control-plane-url> \
  -u <your-email> \
  -t <your-token> \
  -p <project-name> \
  -a true