Terraform module that creates and manages AWS Lightsail resources: instances with their key pairs, block storage, static IPs and firewall rules, plus load balancers, managed relational databases, object storage buckets, certificates, CDN distributions, container services, DNS zones and native alarms.
This module requires Terraform 1.6.0 or later, AWS provider versions from 5.40.0
up to but not including 7.0.0, and AWS Cloud Control (awscc) provider versions
from 1.0.0 up to but not including 2.0.0.
Each resource family is enabled by supplying its input and skipped when that input is left at its default. A single instance with storage, a static IP, an explicit firewall and alarms looks like this:
module "lightsail" {
source = "ganexcloud/lightsail/aws"
version = "~> 1.0"
name = "app-production"
instance = {
availability_zone = "us-east-1a"
blueprint_id = "amazon_linux_2023"
bundle_id = "small_2_0"
}
key_pair = { public_key = var.ssh_public_key }
auto_snapshot = { snapshot_time = "06:00" }
disks = {
data = {
size_in_gb = 20
disk_path = "/dev/xvdf"
}
}
create_static_ip = true
public_ports = [
{ from_port = 22, to_port = 22, protocol = "tcp", cidrs = ["198.51.100.10/32"] },
{ from_port = 443, to_port = 443, protocol = "tcp", cidrs = ["0.0.0.0/0"] },
]
alarms = {
cpu-high = {
metric_name = "CPUUtilization"
comparison_operator = "GreaterThanOrEqualToThreshold"
threshold = 80
evaluation_periods = 2
datapoints_to_alarm = 2
}
}
tags = {
environment = "production"
managed-by = "terraform"
}
}| Family | Enabled by | Creates |
|---|---|---|
| Instance | instance |
instance, optional key pair, disks, static IP, public ports |
| Load balancer | lb |
load balancer, instance attachments, certificate, redirection and stickiness policies |
| Database | database |
managed relational database |
| Bucket | bucket |
bucket, optional access key, resource access grants |
| Certificate | certificate |
Lightsail certificate |
| Distribution | distribution |
CDN distribution |
| Container service | container_service |
container service and optional deployment version |
| DNS | domain_name |
DNS zone and domain_entries records |
| Alarms | alarms |
native Lightsail alarms |
Lightsail resource names are unique per Region across resource types, so a
single name cannot be shared by an instance, its key pair, a load balancer and
a database. The module derives a distinct name per family from name, and the
instance keeps the bare value because it is what callers refer to from outside:
| Family | Default name | Override |
|---|---|---|
| Instance | <name> |
instance.name |
| Key pair | <name>-key |
key_pair.name |
| Static IP | <name>-ip |
static_ip_name |
| Disk | <name>-<disks key> |
disks[*].name |
| Load balancer | <name>-lb |
lb.name |
| Load balancer certificate | <name>-lb-cert |
lb_certificate.name |
| Database | <name>-db |
database.relational_database_name |
| Bucket | <name>-bucket |
bucket.name |
| Certificate | <name>-cert |
certificate.name |
| Distribution | <name>-cdn |
distribution.name |
| Container service | <name>-cs |
container_service.name |
| Alarm | <name>-<alarms key> |
alarms[*].alarm_name |
Lightsail alarms notify a contact method, which is a singleton per account and region. Neither the AWS provider nor Cloud Control exposes it as a resource, so it is not managed here. Create it once before applying, otherwise alarms are created but stay silent:
aws lightsail create-contact-method --protocol Email --contact-endpoint ops@example.comThe email address must then confirm the subscription.
Alarms are created through the awscc provider because the AWS provider has no
Lightsail alarm resource. That provider is therefore a hard requirement of the
module even when alarms is left empty.
By default alarms monitor the instance this module creates. Point them at
another Lightsail resource with alarm_monitored_resource_name.
Lightsail certificates, CDN distributions and DNS zones are global resources
that AWS only exposes through us-east-1. The module deliberately does not
declare a provider configuration alias for them, because that would force every
consumer to pass a second provider even when only creating an instance.
To manage a regional instance and a global distribution together, call the module twice:
module "app" {
source = "ganexcloud/lightsail/aws"
name = "app-production"
instance = {
availability_zone = "sa-east-1a"
blueprint_id = "amazon_linux_2023"
bundle_id = "small_2_0"
}
}
module "app_cdn" {
source = "ganexcloud/lightsail/aws"
providers = { aws = aws.us_east_1 }
name = "app-production"
domain_name = "example.com"
distribution = {
bundle_id = "small_1_0"
origin = {
name = module.app.instance_name
region_name = "sa-east-1"
}
}
}Lightsail runs user_data only on first boot, and the AWS provider forces a
replacement whenever the value changes. Editing it would silently destroy a live
host without re-running anything, so the module ignores subsequent changes to
user_data. Rebuild deliberately when the bootstrap has to run again:
terraform apply -replace='module.lightsail.aws_lightsail_instance.this[0]'A load balancer certificate can only be attached after it is validated. Create
it first, publish the records from the
lb_certificate_domain_validation_records output, then set
lb_certificate_attach = true on a second apply. lb_https_redirection_enabled
requires an attached certificate.
public_portsis authoritative when non-empty: Lightsail replaces the entire rule set, including the ports opened by default at instance creation. Leave it empty to keep the Lightsail defaults.- Lightsail accepts a single add-on per instance, which is why
auto_snapshotis an object rather than a list. bucket_resource_accessaccepts the literal"self"as shorthand for the instance created by this module.- Each change to
container_service_deploymentpublishes a new immutable deployment version; Lightsail keeps the previous ones. - The bucket secret access key and the database master password are stored in Terraform state.
examples/instance— a single host with storage, static IP, firewall and alarms.examples/lb-database— load balancer, certificate and managed database.examples/complete— every resource family.
| Name | Version |
|---|---|
| terraform | >= 1.6.0 |
| aws | >= 5.40.0, < 7.0.0 |
| awscc | >= 1.0.0, < 2.0.0 |
| Name | Version |
|---|---|
| aws | >= 5.40.0, < 7.0.0 |
| awscc | >= 1.0.0, < 2.0.0 |
No modules.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| alarm_monitored_resource_name | Name of the Lightsail resource the alarms monitor. Defaults to the instance created by this module. | string |
null |
no |
| alarms | Lightsail alarms to create, keyed by an arbitrary identifier used as the name suffix. Requires a contact method to already exist in the account; see the README. | map(object({ |
{} |
no |
| auto_snapshot | AutoSnapshot add-on for the instance. Lightsail allows a single add-on per instance. Set to null to disable. | object({ |
null |
no |
| bucket | Object storage bucket to create. Set to null to skip the bucket family. | object({ |
null |
no |
| bucket_resource_access | Names of Lightsail resources (for example instances) granted access to the bucket. Use the literal string "self" to reference the instance created by this module. | list(string) |
[] |
no |
| certificate | Lightsail certificate to create for use with a distribution. Only manageable in us-east-1. Set to null to skip. | object({ |
null |
no |
| container_service | Container service to create. Set to null to skip the container family. | object({ |
null |
no |
| container_service_deployment | Deployment version for the container service. Every change creates a new immutable version. Set to null to leave deployments unmanaged. | object({ |
null |
no |
| create_bucket_access_key | Whether to create an access key for the bucket. The secret is exposed through the bucket_secret_access_key output and stored in state. | bool |
false |
no |
| create_static_ip | Whether to allocate a static IP and attach it to the instance. | bool |
false |
no |
| database | Managed relational database to create. Set to null to skip the database family. | object({ |
null |
no |
| disks | Additional block storage disks to create and attach to the instance, keyed by an arbitrary identifier used as the name suffix. | map(object({ |
{} |
no |
| distribution | CDN distribution to create. Only manageable in us-east-1. Set to null to skip. | object({ |
null |
no |
| domain_entries | Records to create in the Lightsail DNS zone, keyed by an arbitrary identifier. Requires domain_name. | map(object({ |
{} |
no |
| domain_name | Lightsail DNS zone to create. Only manageable in us-east-1. Set to null to skip the DNS family. | string |
null |
no |
| instance | Instance to create. Set to null to skip the instance family. Changing user_data replaces the instance, so the module ignores subsequent changes to it; see the README. | object({ |
null |
no |
| key_pair | SSH key pair to create for the instance. Omit public_key to have Lightsail generate the pair, exposing it through the key_pair_private_key output. Mutually exclusive with key_pair_name. | object({ |
null |
no |
| key_pair_name | Name of an existing Lightsail key pair to attach to the instance. Mutually exclusive with key_pair. | string |
null |
no |
| lb | Load balancer to create. Set to null to skip the load balancer family. | object({ |
null |
no |
| lb_attached_instances | Names of the instances to attach to the load balancer. When empty, the instance created by this module is attached, if any. | list(string) |
[] |
no |
| lb_certificate | TLS certificate to create on the load balancer. Set to null to skip. | object({ |
null |
no |
| lb_certificate_attach | Whether to attach lb_certificate to the load balancer. Attachment only succeeds after the certificate is validated, so this is usually enabled on a second apply. | bool |
false |
no |
| lb_https_redirection_enabled | Whether to redirect HTTP to HTTPS on the load balancer. Set to null to leave the policy unmanaged. Requires an attached certificate. | bool |
null |
no |
| lb_stickiness | Session stickiness policy for the load balancer. Set to null to leave it unmanaged. | object({ |
null |
no |
| name | Base name for the Lightsail resources created by this module. The instance takes it unchanged; every other family derives a suffixed name from it, because Lightsail resource names are unique per Region across resource types. Each family accepts an optional name of its own that overrides this. | string |
n/a | yes |
| public_ports | Public port rules for the instance firewall. An empty list leaves the Lightsail defaults untouched; a non-empty list becomes the authoritative rule set. | list(object({ |
[] |
no |
| static_ip_name | Name of the static IP. Defaults to "-ip". | string |
null |
no |
| tags | Tags applied to every taggable resource created by this module. | map(string) |
{} |
no |
| Name | Description |
|---|---|
| alarm_arns | ARNs of the Lightsail alarms, keyed by the alarms input key. |
| alarm_names | Names of the Lightsail alarms, keyed by the alarms input key. |
| bucket_access_key_id | Access key ID created for the bucket. |
| bucket_arn | ARN of the object storage bucket. |
| bucket_name | Name of the object storage bucket. |
| bucket_secret_access_key | Secret access key created for the bucket. |
| bucket_url | URL of the object storage bucket. |
| certificate_arn | ARN of the Lightsail certificate. |
| certificate_domain_validation_options | DNS records that must be published to validate the Lightsail certificate. |
| certificate_name | Name of the Lightsail certificate. |
| container_service_arn | ARN of the container service. |
| container_service_deployment_version | Version number of the current container service deployment. |
| container_service_name | Name of the container service. |
| container_service_private_domain_name | Private domain name of the container service. |
| container_service_url | Public URL of the container service. |
| database_arn | ARN of the managed relational database. |
| database_master_endpoint_address | Endpoint address of the managed relational database. |
| database_master_endpoint_port | Endpoint port of the managed relational database. |
| database_name | Name of the managed relational database. |
| disk_arns | ARNs of the block storage disks, keyed by the disks input key. |
| disk_names | Names of the block storage disks, keyed by the disks input key. |
| distribution_arn | ARN of the CDN distribution. |
| distribution_domain_name | Domain name of the CDN distribution. |
| distribution_name | Name of the CDN distribution. |
| distribution_status | Status of the CDN distribution. |
| domain_arn | ARN of the Lightsail DNS zone. |
| domain_name | Name of the Lightsail DNS zone. |
| instance_arn | ARN of the Lightsail instance. |
| instance_ipv6_addresses | IPv6 addresses assigned to the instance. |
| instance_name | Name of the Lightsail instance. |
| instance_private_ip_address | Private IP address assigned to the instance. |
| instance_public_ip_address | Public IP address assigned to the instance. |
| instance_username | Default user name for connecting to the instance. |
| key_pair_fingerprint | Fingerprint of the key pair created by this module. |
| key_pair_name | Name of the key pair attached to the instance, whether created here or supplied. |
| key_pair_private_key | Private key generated by Lightsail when key_pair is created without a public_key. |
| lb_arn | ARN of the load balancer. |
| lb_certificate_domain_validation_records | DNS records that must be published to validate the load balancer certificate before it can be attached. |
| lb_certificate_name | Name of the load balancer TLS certificate. |
| lb_dns_name | DNS name of the load balancer. |
| lb_name | Name of the load balancer. |
| static_ip_address | Static IP address allocated for the instance. Point DNS records here. |
| static_ip_name | Name of the static IP allocated for the instance. |
See CONTRIBUTING.md.
Apache 2.0. See LICENSE.