The aws:lightsail/instance:Instance resource, part of the Pulumi AWS provider, provisions Lightsail virtual private servers with pre-configured software blueprints. This guide focuses on three capabilities: blueprint and bundle selection, user data bootstrapping, and automatic snapshot configuration.
Lightsail instances require key pairs created in the Lightsail console and are only available in specific AWS regions. The examples are intentionally small. Combine them with your own networking, firewall rules, and static IP configuration.
Launch a Lightsail instance with SSH access
Most deployments start by selecting a blueprint (the OS and pre-installed software), choosing a bundle (the CPU, RAM, and storage tier), and specifying an availability zone.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lightsail.Instance("example", {
name: "example",
availabilityZone: "us-east-1b",
blueprintId: "amazon_linux_2",
bundleId: "nano_3_0",
keyPairName: "some_key_name",
tags: {
foo: "bar",
},
});
import pulumi
import pulumi_aws as aws
example = aws.lightsail.Instance("example",
name="example",
availability_zone="us-east-1b",
blueprint_id="amazon_linux_2",
bundle_id="nano_3_0",
key_pair_name="some_key_name",
tags={
"foo": "bar",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lightsail"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := lightsail.NewInstance(ctx, "example", &lightsail.InstanceArgs{
Name: pulumi.String("example"),
AvailabilityZone: pulumi.String("us-east-1b"),
BlueprintId: pulumi.String("amazon_linux_2"),
BundleId: pulumi.String("nano_3_0"),
KeyPairName: pulumi.String("some_key_name"),
Tags: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.LightSail.Instance("example", new()
{
Name = "example",
AvailabilityZone = "us-east-1b",
BlueprintId = "amazon_linux_2",
BundleId = "nano_3_0",
KeyPairName = "some_key_name",
Tags =
{
{ "foo", "bar" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lightsail.Instance;
import com.pulumi.aws.lightsail.InstanceArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new Instance("example", InstanceArgs.builder()
.name("example")
.availabilityZone("us-east-1b")
.blueprintId("amazon_linux_2")
.bundleId("nano_3_0")
.keyPairName("some_key_name")
.tags(Map.of("foo", "bar"))
.build());
}
}
resources:
example:
type: aws:lightsail:Instance
properties:
name: example
availabilityZone: us-east-1b
blueprintId: amazon_linux_2
bundleId: nano_3_0
keyPairName: some_key_name
tags:
foo: bar
The blueprintId determines your OS and pre-installed software stack. Use the AWS CLI command aws lightsail get-blueprints to list available options like amazon_linux_2, ubuntu_20_04, or wordpress. The bundleId sets your instance size; nano_3_0 provides minimal resources for testing. The keyPairName enables SSH access using a key pair you’ve created in the Lightsail console.
Bootstrap instances with user data scripts
Applications often need software installed or configuration applied at launch time.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lightsail.Instance("example", {
name: "example",
availabilityZone: "us-east-1b",
blueprintId: "amazon_linux_2",
bundleId: "nano_3_0",
userData: "sudo yum install -y httpd && sudo systemctl start httpd && sudo systemctl enable httpd && echo '<h1>Deployed via Pulumi</h1>' | sudo tee /var/www/html/index.html",
});
import pulumi
import pulumi_aws as aws
example = aws.lightsail.Instance("example",
name="example",
availability_zone="us-east-1b",
blueprint_id="amazon_linux_2",
bundle_id="nano_3_0",
user_data="sudo yum install -y httpd && sudo systemctl start httpd && sudo systemctl enable httpd && echo '<h1>Deployed via Pulumi</h1>' | sudo tee /var/www/html/index.html")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lightsail"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := lightsail.NewInstance(ctx, "example", &lightsail.InstanceArgs{
Name: pulumi.String("example"),
AvailabilityZone: pulumi.String("us-east-1b"),
BlueprintId: pulumi.String("amazon_linux_2"),
BundleId: pulumi.String("nano_3_0"),
UserData: pulumi.String("sudo yum install -y httpd && sudo systemctl start httpd && sudo systemctl enable httpd && echo '<h1>Deployed via Pulumi</h1>' | sudo tee /var/www/html/index.html"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.LightSail.Instance("example", new()
{
Name = "example",
AvailabilityZone = "us-east-1b",
BlueprintId = "amazon_linux_2",
BundleId = "nano_3_0",
UserData = "sudo yum install -y httpd && sudo systemctl start httpd && sudo systemctl enable httpd && echo '<h1>Deployed via Pulumi</h1>' | sudo tee /var/www/html/index.html",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lightsail.Instance;
import com.pulumi.aws.lightsail.InstanceArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new Instance("example", InstanceArgs.builder()
.name("example")
.availabilityZone("us-east-1b")
.blueprintId("amazon_linux_2")
.bundleId("nano_3_0")
.userData("sudo yum install -y httpd && sudo systemctl start httpd && sudo systemctl enable httpd && echo '<h1>Deployed via Pulumi</h1>' | sudo tee /var/www/html/index.html")
.build());
}
}
resources:
example:
type: aws:lightsail:Instance
properties:
name: example
availabilityZone: us-east-1b
blueprintId: amazon_linux_2
bundleId: nano_3_0
userData: sudo yum install -y httpd && sudo systemctl start httpd && sudo systemctl enable httpd && echo '<h1>Deployed via Pulumi</h1>' | sudo tee /var/www/html/index.html
The userData property runs a shell script when the instance first boots. Unlike EC2, Lightsail requires user data as a single-line string. This example installs Apache, starts the service, and creates a basic index page. The script runs with root privileges and executes only once at launch.
Enable automatic daily snapshots
Production instances need backup protection against data loss or configuration errors.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lightsail.Instance("example", {
name: "example",
availabilityZone: "us-east-1b",
blueprintId: "amazon_linux_2",
bundleId: "nano_3_0",
addOn: {
type: "AutoSnapshot",
snapshotTime: "06:00",
status: "Enabled",
},
tags: {
foo: "bar",
},
});
import pulumi
import pulumi_aws as aws
example = aws.lightsail.Instance("example",
name="example",
availability_zone="us-east-1b",
blueprint_id="amazon_linux_2",
bundle_id="nano_3_0",
add_on={
"type": "AutoSnapshot",
"snapshot_time": "06:00",
"status": "Enabled",
},
tags={
"foo": "bar",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lightsail"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := lightsail.NewInstance(ctx, "example", &lightsail.InstanceArgs{
Name: pulumi.String("example"),
AvailabilityZone: pulumi.String("us-east-1b"),
BlueprintId: pulumi.String("amazon_linux_2"),
BundleId: pulumi.String("nano_3_0"),
AddOn: &lightsail.InstanceAddOnArgs{
Type: pulumi.String("AutoSnapshot"),
SnapshotTime: pulumi.String("06:00"),
Status: pulumi.String("Enabled"),
},
Tags: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.LightSail.Instance("example", new()
{
Name = "example",
AvailabilityZone = "us-east-1b",
BlueprintId = "amazon_linux_2",
BundleId = "nano_3_0",
AddOn = new Aws.LightSail.Inputs.InstanceAddOnArgs
{
Type = "AutoSnapshot",
SnapshotTime = "06:00",
Status = "Enabled",
},
Tags =
{
{ "foo", "bar" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lightsail.Instance;
import com.pulumi.aws.lightsail.InstanceArgs;
import com.pulumi.aws.lightsail.inputs.InstanceAddOnArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new Instance("example", InstanceArgs.builder()
.name("example")
.availabilityZone("us-east-1b")
.blueprintId("amazon_linux_2")
.bundleId("nano_3_0")
.addOn(InstanceAddOnArgs.builder()
.type("AutoSnapshot")
.snapshotTime("06:00")
.status("Enabled")
.build())
.tags(Map.of("foo", "bar"))
.build());
}
}
resources:
example:
type: aws:lightsail:Instance
properties:
name: example
availabilityZone: us-east-1b
blueprintId: amazon_linux_2
bundleId: nano_3_0
addOn:
type: AutoSnapshot
snapshotTime: 06:00
status: Enabled
tags:
foo: bar
The addOn property configures Lightsail’s AutoSnapshot feature. Set type to “AutoSnapshot”, specify a snapshotTime in 24-hour format (UTC), and set status to “Enabled”. Lightsail creates daily backups automatically at the specified time, retaining them according to your retention policy.
Beyond these examples
These snippets focus on specific Lightsail instance features: blueprint and bundle selection, user data bootstrapping, and automatic snapshot scheduling. They’re intentionally minimal rather than full server deployments.
The examples reference pre-existing infrastructure such as Lightsail key pairs created in the Lightsail console (not via aws.ec2.KeyPair). They focus on instance configuration rather than provisioning the surrounding infrastructure.
To keep things focused, common Lightsail patterns are omitted, including:
- Static IP assignment (isStaticIp output only)
- IP address type configuration (ipAddressType for IPv4/IPv6/dual-stack)
- Networking and firewall rules
- Instance state management (start/stop)
These omissions are intentional: the goal is to illustrate how each Lightsail feature is wired, not provide drop-in server modules. See the Lightsail Instance resource reference for all available configuration options.
Let's create AWS Lightsail Instances
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Getting Started & Availability
Use these AWS CLI commands:
- Blueprints:
aws lightsail get-blueprints - Bundles:
aws lightsail get-bundles - Availability zones:
aws lightsail get-regions --include-availability-zones
Configuration & Limitations
availabilityZone, blueprintId, bundleId, name, keyPairName, and userData. Plan these values carefully during initial creation.&& operators, as shown in the user data example with Apache installation.aws.ec2.KeyPair with Lightsail instances. Key pairs must be created in the Lightsail console.Features & Add-ons
addOn property with type: "AutoSnapshot", set snapshotTime (e.g., “06:00”), and set status: "Enabled".dualstack (default), ipv4, and ipv6. Configure using the ipAddressType property.