Create AWS Lightsail Key Pairs

The aws:lightsail/keyPair:KeyPair resource, part of the Pulumi AWS provider, manages SSH key pairs specifically for Lightsail instances. Lightsail key pairs are separate from EC2 key pairs and cannot be shared between the two services. This guide focuses on three capabilities: generating new key pairs, encrypting private keys with PGP, and importing existing public keys.

Lightsail key pairs are standalone resources but require deployment to Lightsail-supported regions. Some examples reference PGP keys or local SSH files. The examples are intentionally small. Combine them with your own Lightsail instances and access policies.

Generate a new key pair for Lightsail instances

Most deployments start by generating a new SSH key pair that Lightsail manages for instance access.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.lightsail.KeyPair("example", {name: "example"});
import pulumi
import pulumi_aws as aws

example = aws.lightsail.KeyPair("example", name="example")
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.NewKeyPair(ctx, "example", &lightsail.KeyPairArgs{
			Name: pulumi.String("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 example = new Aws.LightSail.KeyPair("example", new()
    {
        Name = "example",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lightsail.KeyPair;
import com.pulumi.aws.lightsail.KeyPairArgs;
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 KeyPair("example", KeyPairArgs.builder()
            .name("example")
            .build());

    }
}
resources:
  example:
    type: aws:lightsail:KeyPair
    properties:
      name: example

When you create a key pair without specifying a public key, Lightsail generates both the public and private keys. The private key material is stored in Pulumi state as the privateKey output property. Without pgpKey, this private key is stored unencrypted in state files.

Encrypt private key material with PGP

To protect private key material in state files, encrypt it using a PGP key before storage.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.lightsail.KeyPair("example", {
    name: "example",
    pgpKey: "keybase:keybaseusername",
});
import pulumi
import pulumi_aws as aws

example = aws.lightsail.KeyPair("example",
    name="example",
    pgp_key="keybase:keybaseusername")
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.NewKeyPair(ctx, "example", &lightsail.KeyPairArgs{
			Name:   pulumi.String("example"),
			PgpKey: pulumi.String("keybase:keybaseusername"),
		})
		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.KeyPair("example", new()
    {
        Name = "example",
        PgpKey = "keybase:keybaseusername",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lightsail.KeyPair;
import com.pulumi.aws.lightsail.KeyPairArgs;
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 KeyPair("example", KeyPairArgs.builder()
            .name("example")
            .pgpKey("keybase:keybaseusername")
            .build());

    }
}
resources:
  example:
    type: aws:lightsail:KeyPair
    properties:
      name: example
      pgpKey: keybase:keybaseusername

The pgpKey property accepts a PGP key identifier (like a Keybase username or a base64-encoded public key). When provided, Lightsail encrypts the private key material before returning it. The encryptedPrivateKey output contains the encrypted material; you decrypt it locally using your PGP private key. This prevents plaintext private keys from appearing in state snapshots.

Import an existing SSH public key

Organizations with established SSH key management can import existing public keys rather than generating new pairs.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as std from "@pulumi/std";

const example = new aws.lightsail.KeyPair("example", {
    name: "example",
    publicKey: std.file({
        input: "~/.ssh/id_rsa.pub",
    }).then(invoke => invoke.result),
});
import pulumi
import pulumi_aws as aws
import pulumi_std as std

example = aws.lightsail.KeyPair("example",
    name="example",
    public_key=std.file(input="~/.ssh/id_rsa.pub").result)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lightsail"
	"github.com/pulumi/pulumi-std/sdk/go/std"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		invokeFile, err := std.File(ctx, &std.FileArgs{
			Input: "~/.ssh/id_rsa.pub",
		}, nil)
		if err != nil {
			return err
		}
		_, err = lightsail.NewKeyPair(ctx, "example", &lightsail.KeyPairArgs{
			Name:      pulumi.String("example"),
			PublicKey: pulumi.String(invokeFile.Result),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
using Std = Pulumi.Std;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.LightSail.KeyPair("example", new()
    {
        Name = "example",
        PublicKey = Std.File.Invoke(new()
        {
            Input = "~/.ssh/id_rsa.pub",
        }).Apply(invoke => invoke.Result),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lightsail.KeyPair;
import com.pulumi.aws.lightsail.KeyPairArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.FileArgs;
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 KeyPair("example", KeyPairArgs.builder()
            .name("example")
            .publicKey(StdFunctions.file(FileArgs.builder()
                .input("~/.ssh/id_rsa.pub")
                .build()).result())
            .build());

    }
}
resources:
  example:
    type: aws:lightsail:KeyPair
    properties:
      name: example
      publicKey:
        fn::invoke:
          function: std:file
          arguments:
            input: ~/.ssh/id_rsa.pub
          return: result

The publicKey property accepts the contents of an SSH public key file. When you import a public key, Lightsail never receives or stores the corresponding private key. You manage the private key separately through your existing key management system. This lets you reuse keys across infrastructure while keeping Lightsail instances accessible.

Beyond these examples

These snippets focus on specific key pair features: key pair generation and PGP encryption, and existing public key import. They’re intentionally minimal rather than full access management solutions.

The examples may reference pre-existing infrastructure such as PGP keys for encryption, and SSH public key files for import. They focus on key pair configuration rather than provisioning the surrounding access infrastructure.

To keep things focused, common key pair patterns are omitted, including:

  • Resource tagging (tags property)
  • Custom region placement (region property)
  • Name prefix generation (namePrefix property)
  • Key rotation or replacement workflows

These omissions are intentional: the goal is to illustrate how each key pair feature is wired, not provide drop-in access management modules. See the Lightsail KeyPair resource reference for all available configuration options.

Let's create AWS Lightsail Key Pairs

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Security & Encryption
Why should I use a PGP key when creating a Lightsail key pair?
Without a PGP key, the private key material will be stored in state unencrypted. Using pgpKey encrypts the private key material for security.
How do I encrypt my private key with PGP?
Set pgpKey to your PGP key identifier (e.g., keybase:keybaseusername) when creating a new key pair. The encrypted private key will be available in encryptedPrivateKey.
Can I use pgpKey when importing my own public key?
No, pgpKey is ignored when publicKey is supplied. PGP encryption only applies when creating a new key pair.
Key Creation & Import
Can I import an existing Lightsail key pair into Pulumi?
No, you cannot import existing Lightsail key pairs because the private and public keys are only available on initial creation. You can only import the public key material using publicKey.
How do I import my existing SSH public key into Lightsail?
Use the publicKey parameter with the contents of your public key file. The example shows reading from ~/.ssh/id_rsa.pub using std.file().
Configuration & Immutability
Can I change the key pair name after creation?
No, name, namePrefix, publicKey, and pgpKey are all immutable. Changing these properties will force resource replacement.
Service & Regional Availability
What's the difference between Lightsail and EC2 key pairs?
Lightsail key pairs are separate from EC2 key pairs and are specifically required for Lightsail instances. You must use this resource to create or import keys for Lightsail.
Is Lightsail available in all AWS regions?
No, Lightsail is only supported in a limited number of AWS regions. Check the AWS documentation for current regional availability.

Using a different cloud?

Explore security guides for other cloud providers: