Skip to content

Create Module

This guide provides instructions for creating a basic Nullstone module. This guide is specific to AWS; however, the concepts work for other cloud providers as well. We are going to create a simple s3 bucket in this example.

A working copy of this code can be found at https://github.com/nullstone-modules/create-module-guide.

If you are unfamiliar with Terraform, it may be helpful to follow their basic guide.

Prerequisites

This guide requires the following:

  1. An AWS Account
  2. Install/Configure Nullstone CLI
  3. Install Terraform CLI

Configure organization for testing

To start developing modules, you will need the following:

  • aws-sandbox provider (used to test module)
  • sandbox stack
  • sandbox environment connected to aws-sandbox provider

Create sandbox provider

Follow the guide to Connect to AWS to create a provider named aws-sandbox.

Create sandbox stack/environment

Create a Nullstone sandbox stack and environment to test a Nullstone module.

sh
nullstone stacks new --name=sandbox --description="Sandbox for module testing"
nullstone envs new --name=sandbox --stack=sandbox --provider=aws-sandbox --region=us-east-1
nullstone stacks new --name=sandbox --description="Sandbox for module testing"
nullstone envs new --name=sandbox --stack=sandbox --provider=aws-sandbox --region=us-east-1

Create module

Create a new repository/directory to store the module. We recommend having a repository for each module; however, you may have multiple modules in a single repository as long as they are in different directories.

sh
mkdir s3-bucket && cd s3-bucket
git init
mkdir s3-bucket && cd s3-bucket
git init

Now that your repository/directory is established, let's create our module.

sh
nullstone modules generate --register
# This command will ask you a set of questions to configure the module
# Specify the following:
#   Organization: <your organization>
#   Module Name: s3-bucket
#   Friendly Name: S3 Bucket
#   Description: Creates a private S3 bucket
#   Category: datastore
#   Type: datastore/aws-s3
#   ProviderTypes: aws
nullstone modules generate --register
# This command will ask you a set of questions to configure the module
# Specify the following:
#   Organization: <your organization>
#   Module Name: s3-bucket
#   Friendly Name: S3 Bucket
#   Description: Creates a private S3 bucket
#   Category: datastore
#   Type: datastore/aws-s3
#   ProviderTypes: aws

This will generate the following files

  • .nullstone/module.yml - manifest describing the module
  • nullstone.tf - generated Terraform to get you started

The --register flag will register the module in Nullstone. If you wish to omit, issue the following to register the module separately.

sh
nullstone modules new
nullstone modules new

Configure local for testing

To test your module, create a block in Nullstone named sandbox in the sandbox stack. Then, change the active workspace to use the new block in the sandbox environment.

sh
nullstone blocks new --name=test-s3-bucket --stack=sandbox --module=<your organization>/s3-bucket
nullstone workspaces select --block=test-s3-bucket --env=sandbox
nullstone blocks new --name=test-s3-bucket --stack=sandbox --module=<your organization>/s3-bucket
nullstone workspaces select --block=test-s3-bucket --env=sandbox

Build module

Create a file named bucket.tf with the following code. Note that the bucket name and tags are generated in nullstone.tf that we configured previously.

hcl
resource "aws_s3_bucket" "this" {
  bucket        = local.resource_name
  tags          = local.tags
  force_destroy = true
}

resource "aws_s3_bucket_acl" "this" {
  bucket = aws_s3_bucket.this.id
  acl    = "private"
}

resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
  bucket = aws_s3_bucket.this.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "aws:kms"
    }
  }
}
resource "aws_s3_bucket" "this" {
  bucket        = local.resource_name
  tags          = local.tags
  force_destroy = true
}

resource "aws_s3_bucket_acl" "this" {
  bucket = aws_s3_bucket.this.id
  acl    = "private"
}

resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
  bucket = aws_s3_bucket.this.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "aws:kms"
    }
  }
}

Now add outputs to an outputs.tf. Note the description of each output string ||| .... This informs Nullstone of the expected data type of the output.

hcl
output "db_arn" {
  value       = aws_s3_bucket.this.arn
  description = "string ||| The ARN of the created S3 bucket."
}

output "db_protocol" {
  value       = "s3"
  description = "string ||| The protocol used to connect to the s3 bucket."
}

output "db_hostname" {
  value       = aws_s3_bucket.this.bucket
  description = "string ||| The name of the created S3 bucket."
}

output "db_port" {
  value       = ""
  description = "string ||| The port for s3 buckets is blank."
}
output "db_arn" {
  value       = aws_s3_bucket.this.arn
  description = "string ||| The ARN of the created S3 bucket."
}

output "db_protocol" {
  value       = "s3"
  description = "string ||| The protocol used to connect to the s3 bucket."
}

output "db_hostname" {
  value       = aws_s3_bucket.this.bucket
  description = "string ||| The name of the created S3 bucket."
}

output "db_port" {
  value       = ""
  description = "string ||| The port for s3 buckets is blank."
}

Apply infrastructure changes

Now that we have AWS resources in our Terraform, we need to download the AWS Terraform provider.

sh
terraform init
terraform init

Next, authenticate with AWS and export AWS_REGION, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY. These access keys should have access to the aws-sandbox provider. Run terraform to test out the module.

sh
export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=<access key id>
export AWS_SECRET_ACCESS_KEY=<secret access key>

terraform apply
export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=<access key id>
export AWS_SECRET_ACCESS_KEY=<secret access key>

terraform apply

Publish module

Once your module is complete, publish the module to the Nullstone registry. A user can launch this module directly from the Nullstone UI without any coding or Terraform setup.

sh
nullstone modules publish --version=v0.0.1
nullstone modules publish --version=v0.0.1