Capabilities
Capability Modules provide infrastructure to extend and connect Applications to other areas of your infrastructure.
These modules are unique because they are normal Terraform, but never created in their own workspace. Instead, capabilities are attached to applications and managed by the connected application.
Subcategories
These modules provide glue and automatic configuration across 6 major subcategories:
datastores
When creating capabilities that connect applications to datastores, make sure to configure the following:
- Grant network access from the application to the datastore. (see Network Access)
- Generate/Configure credentials that the application can use to access the datastore.
- Output the credentials and URL as secrets to be injected into the application. (see Secrets and Environment Variables)
Example modules:
events
When creating capabilities that trigger events, make sure to configure the following:
- Configure the trigger in the cloud provider.
- [Optional] Grant IAM privileges to the application.
- [Optional] Grant network access to the application.
Example modules:
ingress
When creating capabilities that provide public access, make sure to configure the following:
- Grant network access from the ingress device to the application.
- Connect/Register app with ingress device.
- [Optional] Configure subdomain connection and SSL cert to the ingress device.
Example modules:
- nullstone-modules/aws-load-balancer
- nullstone-modules/aws-s3-cdn
- nullstone-modules/aws-lambda-api-gateway
secrets
When creating capabilities that provide secrets, make sure to configure the following:
- Generate/Receive secrets.
- Output
secrets
outputs.
Example modules:
sidecars
When creating capabilities that provide sidecar containers, make sure to configure the following:
- Output
sidecars
outputs containing definitions used to attach containers to the application definition.
Example modules:
telemetry
When creating capabilities that emit logs/metrics to telemetry providers, make sure to configure the following:
- Redirect/Subscribe log stream
- Tag output log stream with vendor-specific tags marking the stack, environment, and application
Example modules:
Features
Network Access
Application modules create a network identity (e.g. in AWS, Security Group) and inject this into capability modules. When creating a capability module that connects two devices in a cloud provider, make sure to grant network access.
Here is an example snippet from nullstone-modules/aws-postgres-access. Note that the security_group_id
is injected by the application and the database port and security group come from a connection to a postgres datastore.
locals {
security_group_id = var.app_metadata["security_group_id"]
db_endpoint = data.ns_connection.postgres.outputs.db_endpoint
db_subdomain = split(":", local.db_endpoint)[0]
db_port = split(":", local.db_endpoint)[1]
db_security_group_id = data.ns_connection.postgres.outputs.db_security_group_id
}
resource "aws_security_group_rule" "app-to-datastore" {
security_group_id = local.security_group_id
type = "egress"
from_port = local.db_port
to_port = local.db_port
protocol = "tcp"
source_security_group_id = local.db_security_group_id
}
resource "aws_security_group_rule" "datastore-from-app" {
security_group_id = local.db_security_group_id
type = "ingress"
from_port = local.db_port
to_port = local.db_port
protocol = "tcp"
source_security_group_id = local.security_group_id
}
Environment Variables
You can automatically inject environment variables into applications from a capability module. This is done through the env
outputs of the capability module. These environment variables are treated as non-sensitive configuration.
The following example from the nullstone-modules/aws-postgres-access illustrates how to inject non-sensitive sensitive configuration into an application from a capability.
output "env" {
value = [
{
name = "POSTGRES_DB"
value = local.database_name
}
]
}
Secrets
You can securely inject secrets into applications from a capability module. This is done through the secrets
outputs of the capability module. The format is identical to environment variables (name
, value
).
The following example from the nullstone-modules/aws-postgres-access illustrates how to inject sensitive configuration into an application from a capability.
output "secrets" {
value = [
{
name = "POSTGRES_URL"
value = "postgres://${urlencode(local.username)}:${urlencode(random_password.this.result)}@${local.db_endpoint}/${urlencode(local.database_name)}"
}
]
}