The aws:lightsail/distribution:Distribution resource, part of the Pulumi AWS provider, defines a Lightsail CDN distribution that caches content at edge locations to reduce latency for users accessing your content. This guide focuses on three capabilities: bucket origins for static assets, instance origins for application content, and load balancer origins for high-availability applications.
Distributions require an existing Lightsail origin resource and may depend on static IP or load balancer attachments being configured first. The examples are intentionally small. Combine them with your own SSL certificates, custom cache behaviors, and monitoring.
Distribute content from a Lightsail bucket
Most CDN deployments cache static assets stored in object storage, reducing latency for users accessing images, videos, or other files.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lightsail.Bucket("example", {
name: "example-bucket",
bundleId: "small_1_0",
});
const exampleDistribution = new aws.lightsail.Distribution("example", {
name: "example-distribution",
bundleId: "small_1_0",
origin: {
name: example.name,
regionName: example.region,
},
defaultCacheBehavior: {
behavior: "cache",
},
cacheBehaviorSettings: {
allowedHttpMethods: "GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE",
cachedHttpMethods: "GET,HEAD",
defaultTtl: 86400,
maximumTtl: 31536000,
minimumTtl: 0,
forwardedCookies: {
option: "none",
},
forwardedHeaders: {
option: "default",
},
forwardedQueryStrings: {
option: false,
},
},
});
import pulumi
import pulumi_aws as aws
example = aws.lightsail.Bucket("example",
name="example-bucket",
bundle_id="small_1_0")
example_distribution = aws.lightsail.Distribution("example",
name="example-distribution",
bundle_id="small_1_0",
origin={
"name": example.name,
"region_name": example.region,
},
default_cache_behavior={
"behavior": "cache",
},
cache_behavior_settings={
"allowed_http_methods": "GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE",
"cached_http_methods": "GET,HEAD",
"default_ttl": 86400,
"maximum_ttl": 31536000,
"minimum_ttl": 0,
"forwarded_cookies": {
"option": "none",
},
"forwarded_headers": {
"option": "default",
},
"forwarded_query_strings": {
"option": False,
},
})
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 {
example, err := lightsail.NewBucket(ctx, "example", &lightsail.BucketArgs{
Name: pulumi.String("example-bucket"),
BundleId: pulumi.String("small_1_0"),
})
if err != nil {
return err
}
_, err = lightsail.NewDistribution(ctx, "example", &lightsail.DistributionArgs{
Name: pulumi.String("example-distribution"),
BundleId: pulumi.String("small_1_0"),
Origin: &lightsail.DistributionOriginArgs{
Name: example.Name,
RegionName: example.Region,
},
DefaultCacheBehavior: &lightsail.DistributionDefaultCacheBehaviorArgs{
Behavior: pulumi.String("cache"),
},
CacheBehaviorSettings: &lightsail.DistributionCacheBehaviorSettingsArgs{
AllowedHttpMethods: pulumi.String("GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE"),
CachedHttpMethods: pulumi.String("GET,HEAD"),
DefaultTtl: pulumi.Int(86400),
MaximumTtl: pulumi.Int(31536000),
MinimumTtl: pulumi.Int(0),
ForwardedCookies: &lightsail.DistributionCacheBehaviorSettingsForwardedCookiesArgs{
Option: pulumi.String("none"),
},
ForwardedHeaders: &lightsail.DistributionCacheBehaviorSettingsForwardedHeadersArgs{
Option: pulumi.String("default"),
},
ForwardedQueryStrings: &lightsail.DistributionCacheBehaviorSettingsForwardedQueryStringsArgs{
Option: pulumi.Bool(false),
},
},
})
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.Bucket("example", new()
{
Name = "example-bucket",
BundleId = "small_1_0",
});
var exampleDistribution = new Aws.LightSail.Distribution("example", new()
{
Name = "example-distribution",
BundleId = "small_1_0",
Origin = new Aws.LightSail.Inputs.DistributionOriginArgs
{
Name = example.Name,
RegionName = example.Region,
},
DefaultCacheBehavior = new Aws.LightSail.Inputs.DistributionDefaultCacheBehaviorArgs
{
Behavior = "cache",
},
CacheBehaviorSettings = new Aws.LightSail.Inputs.DistributionCacheBehaviorSettingsArgs
{
AllowedHttpMethods = "GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE",
CachedHttpMethods = "GET,HEAD",
DefaultTtl = 86400,
MaximumTtl = 31536000,
MinimumTtl = 0,
ForwardedCookies = new Aws.LightSail.Inputs.DistributionCacheBehaviorSettingsForwardedCookiesArgs
{
Option = "none",
},
ForwardedHeaders = new Aws.LightSail.Inputs.DistributionCacheBehaviorSettingsForwardedHeadersArgs
{
Option = "default",
},
ForwardedQueryStrings = new Aws.LightSail.Inputs.DistributionCacheBehaviorSettingsForwardedQueryStringsArgs
{
Option = false,
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lightsail.Bucket;
import com.pulumi.aws.lightsail.BucketArgs;
import com.pulumi.aws.lightsail.Distribution;
import com.pulumi.aws.lightsail.DistributionArgs;
import com.pulumi.aws.lightsail.inputs.DistributionOriginArgs;
import com.pulumi.aws.lightsail.inputs.DistributionDefaultCacheBehaviorArgs;
import com.pulumi.aws.lightsail.inputs.DistributionCacheBehaviorSettingsArgs;
import com.pulumi.aws.lightsail.inputs.DistributionCacheBehaviorSettingsForwardedCookiesArgs;
import com.pulumi.aws.lightsail.inputs.DistributionCacheBehaviorSettingsForwardedHeadersArgs;
import com.pulumi.aws.lightsail.inputs.DistributionCacheBehaviorSettingsForwardedQueryStringsArgs;
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 Bucket("example", BucketArgs.builder()
.name("example-bucket")
.bundleId("small_1_0")
.build());
var exampleDistribution = new Distribution("exampleDistribution", DistributionArgs.builder()
.name("example-distribution")
.bundleId("small_1_0")
.origin(DistributionOriginArgs.builder()
.name(example.name())
.regionName(example.region())
.build())
.defaultCacheBehavior(DistributionDefaultCacheBehaviorArgs.builder()
.behavior("cache")
.build())
.cacheBehaviorSettings(DistributionCacheBehaviorSettingsArgs.builder()
.allowedHttpMethods("GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE")
.cachedHttpMethods("GET,HEAD")
.defaultTtl(86400)
.maximumTtl(31536000)
.minimumTtl(0)
.forwardedCookies(DistributionCacheBehaviorSettingsForwardedCookiesArgs.builder()
.option("none")
.build())
.forwardedHeaders(DistributionCacheBehaviorSettingsForwardedHeadersArgs.builder()
.option("default")
.build())
.forwardedQueryStrings(DistributionCacheBehaviorSettingsForwardedQueryStringsArgs.builder()
.option(false)
.build())
.build())
.build());
}
}
resources:
example:
type: aws:lightsail:Bucket
properties:
name: example-bucket
bundleId: small_1_0
exampleDistribution:
type: aws:lightsail:Distribution
name: example
properties:
name: example-distribution
bundleId: small_1_0
origin:
name: ${example.name}
regionName: ${example.region}
defaultCacheBehavior:
behavior: cache
cacheBehaviorSettings:
allowedHttpMethods: GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE
cachedHttpMethods: GET,HEAD
defaultTtl: 86400
maximumTtl: 3.1536e+07
minimumTtl: 0
forwardedCookies:
option: none
forwardedHeaders:
option: default
forwardedQueryStrings:
option: false
The origin property points to your Lightsail bucket by name and region. The defaultCacheBehavior sets whether content is cached at edge locations. The cacheBehaviorSettings block controls HTTP methods, TTL values, and what headers or cookies are forwarded to the origin. Here, GET and HEAD requests are cached for up to 24 hours (86400 seconds), with a maximum TTL of one year.
Distribute content from a Lightsail instance
Applications running on instances can benefit from CDN caching to reduce origin load and improve response times.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const available = aws.getAvailabilityZones({
state: "available",
filters: [{
name: "opt-in-status",
values: ["opt-in-not-required"],
}],
});
const exampleStaticIp = new aws.lightsail.StaticIp("example", {name: "example-static-ip"});
const exampleInstance = new aws.lightsail.Instance("example", {
name: "example-instance",
availabilityZone: available.then(available => available.names?.[0]),
blueprintId: "amazon_linux_2",
bundleId: "micro_1_0",
});
const example = new aws.lightsail.StaticIpAttachment("example", {
staticIpName: exampleStaticIp.name,
instanceName: exampleInstance.name,
});
const exampleDistribution = new aws.lightsail.Distribution("example", {
name: "example-distribution",
bundleId: "small_1_0",
origin: {
name: exampleInstance.name,
regionName: available.then(available => available.id),
},
defaultCacheBehavior: {
behavior: "cache",
},
}, {
dependsOn: [example],
});
import pulumi
import pulumi_aws as aws
available = aws.get_availability_zones(state="available",
filters=[{
"name": "opt-in-status",
"values": ["opt-in-not-required"],
}])
example_static_ip = aws.lightsail.StaticIp("example", name="example-static-ip")
example_instance = aws.lightsail.Instance("example",
name="example-instance",
availability_zone=available.names[0],
blueprint_id="amazon_linux_2",
bundle_id="micro_1_0")
example = aws.lightsail.StaticIpAttachment("example",
static_ip_name=example_static_ip.name,
instance_name=example_instance.name)
example_distribution = aws.lightsail.Distribution("example",
name="example-distribution",
bundle_id="small_1_0",
origin={
"name": example_instance.name,
"region_name": available.id,
},
default_cache_behavior={
"behavior": "cache",
},
opts = pulumi.ResourceOptions(depends_on=[example]))
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"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 {
available, err := aws.GetAvailabilityZones(ctx, &aws.GetAvailabilityZonesArgs{
State: pulumi.StringRef("available"),
Filters: []aws.GetAvailabilityZonesFilter{
{
Name: "opt-in-status",
Values: []string{
"opt-in-not-required",
},
},
},
}, nil)
if err != nil {
return err
}
exampleStaticIp, err := lightsail.NewStaticIp(ctx, "example", &lightsail.StaticIpArgs{
Name: pulumi.String("example-static-ip"),
})
if err != nil {
return err
}
exampleInstance, err := lightsail.NewInstance(ctx, "example", &lightsail.InstanceArgs{
Name: pulumi.String("example-instance"),
AvailabilityZone: pulumi.String(available.Names[0]),
BlueprintId: pulumi.String("amazon_linux_2"),
BundleId: pulumi.String("micro_1_0"),
})
if err != nil {
return err
}
example, err := lightsail.NewStaticIpAttachment(ctx, "example", &lightsail.StaticIpAttachmentArgs{
StaticIpName: exampleStaticIp.Name,
InstanceName: exampleInstance.Name,
})
if err != nil {
return err
}
_, err = lightsail.NewDistribution(ctx, "example", &lightsail.DistributionArgs{
Name: pulumi.String("example-distribution"),
BundleId: pulumi.String("small_1_0"),
Origin: &lightsail.DistributionOriginArgs{
Name: exampleInstance.Name,
RegionName: pulumi.String(available.Id),
},
DefaultCacheBehavior: &lightsail.DistributionDefaultCacheBehaviorArgs{
Behavior: pulumi.String("cache"),
},
}, pulumi.DependsOn([]pulumi.Resource{
example,
}))
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 available = Aws.GetAvailabilityZones.Invoke(new()
{
State = "available",
Filters = new[]
{
new Aws.Inputs.GetAvailabilityZonesFilterInputArgs
{
Name = "opt-in-status",
Values = new[]
{
"opt-in-not-required",
},
},
},
});
var exampleStaticIp = new Aws.LightSail.StaticIp("example", new()
{
Name = "example-static-ip",
});
var exampleInstance = new Aws.LightSail.Instance("example", new()
{
Name = "example-instance",
AvailabilityZone = available.Apply(getAvailabilityZonesResult => getAvailabilityZonesResult.Names[0]),
BlueprintId = "amazon_linux_2",
BundleId = "micro_1_0",
});
var example = new Aws.LightSail.StaticIpAttachment("example", new()
{
StaticIpName = exampleStaticIp.Name,
InstanceName = exampleInstance.Name,
});
var exampleDistribution = new Aws.LightSail.Distribution("example", new()
{
Name = "example-distribution",
BundleId = "small_1_0",
Origin = new Aws.LightSail.Inputs.DistributionOriginArgs
{
Name = exampleInstance.Name,
RegionName = available.Apply(getAvailabilityZonesResult => getAvailabilityZonesResult.Id),
},
DefaultCacheBehavior = new Aws.LightSail.Inputs.DistributionDefaultCacheBehaviorArgs
{
Behavior = "cache",
},
}, new CustomResourceOptions
{
DependsOn =
{
example,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetAvailabilityZonesArgs;
import com.pulumi.aws.lightsail.StaticIp;
import com.pulumi.aws.lightsail.StaticIpArgs;
import com.pulumi.aws.lightsail.Instance;
import com.pulumi.aws.lightsail.InstanceArgs;
import com.pulumi.aws.lightsail.StaticIpAttachment;
import com.pulumi.aws.lightsail.StaticIpAttachmentArgs;
import com.pulumi.aws.lightsail.Distribution;
import com.pulumi.aws.lightsail.DistributionArgs;
import com.pulumi.aws.lightsail.inputs.DistributionOriginArgs;
import com.pulumi.aws.lightsail.inputs.DistributionDefaultCacheBehaviorArgs;
import com.pulumi.resources.CustomResourceOptions;
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) {
final var available = AwsFunctions.getAvailabilityZones(GetAvailabilityZonesArgs.builder()
.state("available")
.filters(GetAvailabilityZonesFilterArgs.builder()
.name("opt-in-status")
.values("opt-in-not-required")
.build())
.build());
var exampleStaticIp = new StaticIp("exampleStaticIp", StaticIpArgs.builder()
.name("example-static-ip")
.build());
var exampleInstance = new Instance("exampleInstance", InstanceArgs.builder()
.name("example-instance")
.availabilityZone(available.names()[0])
.blueprintId("amazon_linux_2")
.bundleId("micro_1_0")
.build());
var example = new StaticIpAttachment("example", StaticIpAttachmentArgs.builder()
.staticIpName(exampleStaticIp.name())
.instanceName(exampleInstance.name())
.build());
var exampleDistribution = new Distribution("exampleDistribution", DistributionArgs.builder()
.name("example-distribution")
.bundleId("small_1_0")
.origin(DistributionOriginArgs.builder()
.name(exampleInstance.name())
.regionName(available.id())
.build())
.defaultCacheBehavior(DistributionDefaultCacheBehaviorArgs.builder()
.behavior("cache")
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(example)
.build());
}
}
resources:
example:
type: aws:lightsail:StaticIpAttachment
properties:
staticIpName: ${exampleStaticIp.name}
instanceName: ${exampleInstance.name}
exampleStaticIp:
type: aws:lightsail:StaticIp
name: example
properties:
name: example-static-ip
exampleInstance:
type: aws:lightsail:Instance
name: example
properties:
name: example-instance
availabilityZone: ${available.names[0]}
blueprintId: amazon_linux_2
bundleId: micro_1_0
exampleDistribution:
type: aws:lightsail:Distribution
name: example
properties:
name: example-distribution
bundleId: small_1_0
origin:
name: ${exampleInstance.name}
regionName: ${available.id}
defaultCacheBehavior:
behavior: cache
options:
dependsOn:
- ${example}
variables:
available:
fn::invoke:
function: aws:getAvailabilityZones
arguments:
state: available
filters:
- name: opt-in-status
values:
- opt-in-not-required
The origin references your instance by name and region. The dependsOn property ensures the static IP attachment completes before creating the distribution, since distributions require a stable IP address for the origin. Without this dependency, the distribution might attempt to reference an instance without a static IP.
Distribute content from a load balancer
Load-balanced applications use distributions to cache responses while maintaining high availability across multiple backend instances.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const available = aws.getAvailabilityZones({
state: "available",
filters: [{
name: "opt-in-status",
values: ["opt-in-not-required"],
}],
});
const example = new aws.lightsail.Lb("example", {
name: "example-load-balancer",
healthCheckPath: "/",
instancePort: 80,
tags: {
foo: "bar",
},
});
const exampleInstance = new aws.lightsail.Instance("example", {
name: "example-instance",
availabilityZone: available.then(available => available.names?.[0]),
blueprintId: "amazon_linux_2",
bundleId: "nano_3_0",
});
const exampleLbAttachment = new aws.lightsail.LbAttachment("example", {
lbName: example.name,
instanceName: exampleInstance.name,
});
const exampleDistribution = new aws.lightsail.Distribution("example", {
name: "example-distribution",
bundleId: "small_1_0",
origin: {
name: example.name,
regionName: available.then(available => available.id),
},
defaultCacheBehavior: {
behavior: "cache",
},
}, {
dependsOn: [exampleLbAttachment],
});
import pulumi
import pulumi_aws as aws
available = aws.get_availability_zones(state="available",
filters=[{
"name": "opt-in-status",
"values": ["opt-in-not-required"],
}])
example = aws.lightsail.Lb("example",
name="example-load-balancer",
health_check_path="/",
instance_port=80,
tags={
"foo": "bar",
})
example_instance = aws.lightsail.Instance("example",
name="example-instance",
availability_zone=available.names[0],
blueprint_id="amazon_linux_2",
bundle_id="nano_3_0")
example_lb_attachment = aws.lightsail.LbAttachment("example",
lb_name=example.name,
instance_name=example_instance.name)
example_distribution = aws.lightsail.Distribution("example",
name="example-distribution",
bundle_id="small_1_0",
origin={
"name": example.name,
"region_name": available.id,
},
default_cache_behavior={
"behavior": "cache",
},
opts = pulumi.ResourceOptions(depends_on=[example_lb_attachment]))
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"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 {
available, err := aws.GetAvailabilityZones(ctx, &aws.GetAvailabilityZonesArgs{
State: pulumi.StringRef("available"),
Filters: []aws.GetAvailabilityZonesFilter{
{
Name: "opt-in-status",
Values: []string{
"opt-in-not-required",
},
},
},
}, nil)
if err != nil {
return err
}
example, err := lightsail.NewLb(ctx, "example", &lightsail.LbArgs{
Name: pulumi.String("example-load-balancer"),
HealthCheckPath: pulumi.String("/"),
InstancePort: pulumi.Int(80),
Tags: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
})
if err != nil {
return err
}
exampleInstance, err := lightsail.NewInstance(ctx, "example", &lightsail.InstanceArgs{
Name: pulumi.String("example-instance"),
AvailabilityZone: pulumi.String(available.Names[0]),
BlueprintId: pulumi.String("amazon_linux_2"),
BundleId: pulumi.String("nano_3_0"),
})
if err != nil {
return err
}
exampleLbAttachment, err := lightsail.NewLbAttachment(ctx, "example", &lightsail.LbAttachmentArgs{
LbName: example.Name,
InstanceName: exampleInstance.Name,
})
if err != nil {
return err
}
_, err = lightsail.NewDistribution(ctx, "example", &lightsail.DistributionArgs{
Name: pulumi.String("example-distribution"),
BundleId: pulumi.String("small_1_0"),
Origin: &lightsail.DistributionOriginArgs{
Name: example.Name,
RegionName: pulumi.String(available.Id),
},
DefaultCacheBehavior: &lightsail.DistributionDefaultCacheBehaviorArgs{
Behavior: pulumi.String("cache"),
},
}, pulumi.DependsOn([]pulumi.Resource{
exampleLbAttachment,
}))
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 available = Aws.GetAvailabilityZones.Invoke(new()
{
State = "available",
Filters = new[]
{
new Aws.Inputs.GetAvailabilityZonesFilterInputArgs
{
Name = "opt-in-status",
Values = new[]
{
"opt-in-not-required",
},
},
},
});
var example = new Aws.LightSail.Lb("example", new()
{
Name = "example-load-balancer",
HealthCheckPath = "/",
InstancePort = 80,
Tags =
{
{ "foo", "bar" },
},
});
var exampleInstance = new Aws.LightSail.Instance("example", new()
{
Name = "example-instance",
AvailabilityZone = available.Apply(getAvailabilityZonesResult => getAvailabilityZonesResult.Names[0]),
BlueprintId = "amazon_linux_2",
BundleId = "nano_3_0",
});
var exampleLbAttachment = new Aws.LightSail.LbAttachment("example", new()
{
LbName = example.Name,
InstanceName = exampleInstance.Name,
});
var exampleDistribution = new Aws.LightSail.Distribution("example", new()
{
Name = "example-distribution",
BundleId = "small_1_0",
Origin = new Aws.LightSail.Inputs.DistributionOriginArgs
{
Name = example.Name,
RegionName = available.Apply(getAvailabilityZonesResult => getAvailabilityZonesResult.Id),
},
DefaultCacheBehavior = new Aws.LightSail.Inputs.DistributionDefaultCacheBehaviorArgs
{
Behavior = "cache",
},
}, new CustomResourceOptions
{
DependsOn =
{
exampleLbAttachment,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetAvailabilityZonesArgs;
import com.pulumi.aws.lightsail.Lb;
import com.pulumi.aws.lightsail.LbArgs;
import com.pulumi.aws.lightsail.Instance;
import com.pulumi.aws.lightsail.InstanceArgs;
import com.pulumi.aws.lightsail.LbAttachment;
import com.pulumi.aws.lightsail.LbAttachmentArgs;
import com.pulumi.aws.lightsail.Distribution;
import com.pulumi.aws.lightsail.DistributionArgs;
import com.pulumi.aws.lightsail.inputs.DistributionOriginArgs;
import com.pulumi.aws.lightsail.inputs.DistributionDefaultCacheBehaviorArgs;
import com.pulumi.resources.CustomResourceOptions;
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) {
final var available = AwsFunctions.getAvailabilityZones(GetAvailabilityZonesArgs.builder()
.state("available")
.filters(GetAvailabilityZonesFilterArgs.builder()
.name("opt-in-status")
.values("opt-in-not-required")
.build())
.build());
var example = new Lb("example", LbArgs.builder()
.name("example-load-balancer")
.healthCheckPath("/")
.instancePort(80)
.tags(Map.of("foo", "bar"))
.build());
var exampleInstance = new Instance("exampleInstance", InstanceArgs.builder()
.name("example-instance")
.availabilityZone(available.names()[0])
.blueprintId("amazon_linux_2")
.bundleId("nano_3_0")
.build());
var exampleLbAttachment = new LbAttachment("exampleLbAttachment", LbAttachmentArgs.builder()
.lbName(example.name())
.instanceName(exampleInstance.name())
.build());
var exampleDistribution = new Distribution("exampleDistribution", DistributionArgs.builder()
.name("example-distribution")
.bundleId("small_1_0")
.origin(DistributionOriginArgs.builder()
.name(example.name())
.regionName(available.id())
.build())
.defaultCacheBehavior(DistributionDefaultCacheBehaviorArgs.builder()
.behavior("cache")
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(exampleLbAttachment)
.build());
}
}
resources:
example:
type: aws:lightsail:Lb
properties:
name: example-load-balancer
healthCheckPath: /
instancePort: '80'
tags:
foo: bar
exampleInstance:
type: aws:lightsail:Instance
name: example
properties:
name: example-instance
availabilityZone: ${available.names[0]}
blueprintId: amazon_linux_2
bundleId: nano_3_0
exampleLbAttachment:
type: aws:lightsail:LbAttachment
name: example
properties:
lbName: ${example.name}
instanceName: ${exampleInstance.name}
exampleDistribution:
type: aws:lightsail:Distribution
name: example
properties:
name: example-distribution
bundleId: small_1_0
origin:
name: ${example.name}
regionName: ${available.id}
defaultCacheBehavior:
behavior: cache
options:
dependsOn:
- ${exampleLbAttachment}
variables:
available:
fn::invoke:
function: aws:getAvailabilityZones
arguments:
state: available
filters:
- name: opt-in-status
values:
- opt-in-not-required
The origin references your load balancer by name and region. The dependsOn property ensures the instance is attached to the load balancer before creating the distribution. This prevents the distribution from pointing to a load balancer with no healthy backends.
Beyond these examples
These snippets focus on specific distribution-level features: origin configuration for buckets, instances, and load balancers, and cache behavior and TTL settings. They’re intentionally minimal rather than full CDN deployments.
The examples require pre-existing infrastructure such as Lightsail buckets, instances, or load balancers, and static IP attachments or load balancer attachments. They focus on configuring the distribution rather than provisioning the origin resources.
To keep things focused, common distribution patterns are omitted, including:
- Custom SSL/TLS certificates (certificateName)
- Per-path cache behaviors (cacheBehaviors)
- IP address type selection (ipAddressType)
- Distribution enable/disable controls (isEnabled)
These omissions are intentional: the goal is to illustrate how each distribution feature is wired, not provide drop-in CDN modules. See the Lightsail Distribution resource reference for all available configuration options.
Let's create AWS Lightsail CDN Distributions
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Origins & Dependencies
origin property with the resource’s name and regionName.dependsOn for the StaticIpAttachment, and Load Balancer origins require dependsOn for the LbAttachment. This ensures attachments complete before the distribution is created.domainName is a computed output property that becomes available after the distribution is created.Caching Configuration
cacheBehaviorSettings applies globally to all paths, while cacheBehaviors allows per-path overrides for specific URL patterns.defaultTtl (e.g., 86400 for 1 day), maximumTtl (e.g., 31536000 for 1 year), and minimumTtl (e.g., 0 for no minimum).allowedHttpMethods specifies which HTTP methods the distribution accepts (e.g., GET, HEAD, OPTIONS, PUT, PATCH, POST, DELETE), while cachedHttpMethods specifies which methods have their responses cached (typically GET, HEAD).Network & Security
dualstack (IPv4 and IPv6). You can set ipAddressType to ipv4 for IPv4-only.certificateName property to the name of your SSL/TLS certificate.General Configuration
isEnabled: true). Set isEnabled to false to create a disabled distribution.Using a different cloud?
Explore networking guides for other cloud providers: