Create AWS Lightsail Instances

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 FREE

Frequently Asked Questions

Getting Started & Availability
Which AWS regions support Lightsail?
Lightsail is only supported in a limited number of AWS Regions. Check the AWS documentation on “Regions and Availability Zones in Amazon Lightsail” before creating instances.
How do I find available blueprint IDs, bundle IDs, and availability zones?

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
What properties can't be changed after creating a Lightsail instance?
These properties are immutable and require instance replacement if changed: availabilityZone, blueprintId, bundleId, name, keyPairName, and userData. Plan these values carefully during initial creation.
Why can't I use multi-line user data with Lightsail?
Lightsail user data only accepts a single-line string, unlike EC2. Combine multiple commands using && operators, as shown in the user data example with Apache installation.
Can I use EC2 key pairs with Lightsail instances?
No, you cannot use aws.ec2.KeyPair with Lightsail instances. Key pairs must be created in the Lightsail console.
Do Lightsail instance names need to be globally unique?
No, but names must be unique within each AWS Region in your Lightsail account.
Features & Add-ons
How do I enable automatic snapshots for my instance?
Configure the addOn property with type: "AutoSnapshot", set snapshotTime (e.g., “06:00”), and set status: "Enabled".
What IP address types are available for Lightsail instances?
Valid values are dualstack (default), ipv4, and ipv6. Configure using the ipAddressType property.

Using a different cloud?

Explore compute guides for other cloud providers: