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 FREEFrequently Asked Questions
Security & Encryption
pgpKey encrypts the private key material for security.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.pgpKey is ignored when publicKey is supplied. PGP encryption only applies when creating a new key pair.Key Creation & Import
publicKey.publicKey parameter with the contents of your public key file. The example shows reading from ~/.ssh/id_rsa.pub using std.file().Configuration & Immutability
name, namePrefix, publicKey, and pgpKey are all immutable. Changing these properties will force resource replacement.