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 automated snapshot backups.

Lightsail instances require SSH key pairs created in the Lightsail console and must be deployed in Lightsail-supported 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 compute and memory tier), and placing the instance in 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 specifies the OS image; use the AWS CLI command aws lightsail get-blueprints to list available options like “amazon_linux_2” or “ubuntu_20_04”. The bundleId sets the instance size; aws lightsail get-bundles shows tiers from nano to large. The keyPairName must reference a key pair created in the Lightsail console (EC2 key pairs don’t work here).

Bootstrap instances with user data scripts

Applications often need software installed at launch time. Lightsail user data runs shell commands once during the first boot.

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 accepts a single-line string of shell commands. This differs from EC2 user data, which supports multi-line scripts. Here, the script installs Apache, starts the service, and creates an index page. Commands run sequentially; use && to chain them together.

Enable automatic daily snapshots

Production instances need backup protection. Lightsail’s AutoSnapshot add-on creates daily snapshots at a scheduled 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",
    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 block configures the AutoSnapshot feature. Set type to “AutoSnapshot”, specify snapshotTime in 24-hour format (e.g., “06:00” for 6 AM UTC), and set status to “Enabled”. Lightsail retains the seven most recent snapshots automatically.

Beyond these examples

These snippets focus on specific Lightsail instance features: blueprint and bundle selection, user data bootstrapping, and automated snapshot backups. They’re intentionally minimal rather than full server deployments.

The examples may reference pre-existing infrastructure such as SSH key pairs (must be created in Lightsail console) and Lightsail-supported AWS regions. They focus on configuring the instance rather than provisioning networking or access control.

To keep things focused, common Lightsail patterns are omitted, including:

  • Static IP attachment (isStaticIp property)
  • IPv4/IPv6 address type selection (ipAddressType)
  • 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

Regional Availability & Setup
Is Lightsail available in all AWS regions?
No, Lightsail is only supported in a limited number of AWS Regions. Check the Regions and Availability Zones documentation before deploying.
How do I find available blueprints, bundles, 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
Can I use aws.ec2.KeyPair for my Lightsail instance?
No, Lightsail key pairs must be created in the Lightsail console. Reference the key pair by name using the keyPairName property.
Configuration & Immutability
What properties can't I change after creating an instance?
These properties are immutable and will force instance replacement if changed: availabilityZone, blueprintId, bundleId, name, keyPairName, and userData.
What's different about Lightsail user data compared to EC2?
Lightsail user data only accepts a single-line string, unlike EC2’s multi-line scripts. Chain commands using && (e.g., sudo yum install -y httpd && sudo systemctl start httpd).
Do instance names need to be globally unique?
No, but names must be unique within each AWS Region in your Lightsail account.
What IP address types are supported?
Valid values are dualstack (default), ipv4, and ipv6. Configure using the ipAddressType property.
Snapshots & Add-ons
How do I enable automatic snapshots for my instance?
Configure the addOn property with type: "AutoSnapshot", snapshotTime: "06:00" (24-hour format), and status: "Enabled".
What computed properties are available after instance creation?
After creation, you can access cpuCount, ramSize, publicIpAddress, privateIpAddress, ipv6Addresses, username, createdAt, and isStaticIp.

Using a different cloud?

Explore compute guides for other cloud providers: