Configure AWS AMI Launch Permissions

The aws:ec2/amiLaunchPermission:AmiLaunchPermission resource, part of the Pulumi AWS provider, grants launch permissions on an AMI to specific AWS accounts, all accounts, or organization members. This guide focuses on three capabilities: account-specific sharing, public access grants, and organization-wide permissions.

Launch permissions require an existing AMI that you own in the current region. The examples are intentionally small. Combine them with your own AMI creation and management workflows.

Grant launch permission to a specific AWS account

Teams sharing AMIs across AWS accounts grant launch permissions to specific account IDs, allowing cross-account deployments without public exposure.

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

const example = new aws.ec2.AmiLaunchPermission("example", {
    imageId: "ami-12345678",
    accountId: "123456789012",
});
import pulumi
import pulumi_aws as aws

example = aws.ec2.AmiLaunchPermission("example",
    image_id="ami-12345678",
    account_id="123456789012")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := ec2.NewAmiLaunchPermission(ctx, "example", &ec2.AmiLaunchPermissionArgs{
			ImageId:   pulumi.String("ami-12345678"),
			AccountId: pulumi.String("123456789012"),
		})
		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.Ec2.AmiLaunchPermission("example", new()
    {
        ImageId = "ami-12345678",
        AccountId = "123456789012",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.AmiLaunchPermission;
import com.pulumi.aws.ec2.AmiLaunchPermissionArgs;
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 AmiLaunchPermission("example", AmiLaunchPermissionArgs.builder()
            .imageId("ami-12345678")
            .accountId("123456789012")
            .build());

    }
}
resources:
  example:
    type: aws:ec2:AmiLaunchPermission
    properties:
      imageId: ami-12345678
      accountId: '123456789012'

The imageId property identifies your AMI. The accountId property specifies which AWS account can launch instances from it. This creates a one-to-one permission; repeat for multiple accounts.

Make an AMI publicly launchable

Some AMIs need to be available to all AWS accounts, such as when distributing open-source software.

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

const example = new aws.ec2.AmiLaunchPermission("example", {
    imageId: "ami-12345678",
    group: "all",
});
import pulumi
import pulumi_aws as aws

example = aws.ec2.AmiLaunchPermission("example",
    image_id="ami-12345678",
    group="all")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := ec2.NewAmiLaunchPermission(ctx, "example", &ec2.AmiLaunchPermissionArgs{
			ImageId: pulumi.String("ami-12345678"),
			Group:   pulumi.String("all"),
		})
		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.Ec2.AmiLaunchPermission("example", new()
    {
        ImageId = "ami-12345678",
        Group = "all",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.AmiLaunchPermission;
import com.pulumi.aws.ec2.AmiLaunchPermissionArgs;
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 AmiLaunchPermission("example", AmiLaunchPermissionArgs.builder()
            .imageId("ami-12345678")
            .group("all")
            .build());

    }
}
resources:
  example:
    type: aws:ec2:AmiLaunchPermission
    properties:
      imageId: ami-12345678
      group: all

Setting group to “all” makes the AMI publicly launchable by any AWS account. This is the only valid value for the group property.

Share an AMI across an AWS Organization

Organizations with multiple AWS accounts share AMIs across all member accounts without managing individual permissions.

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

const current = aws.organizations.getOrganization({});
const example = new aws.ec2.AmiLaunchPermission("example", {
    imageId: "ami-12345678",
    organizationArn: current.then(current => current.arn),
});
import pulumi
import pulumi_aws as aws

current = aws.organizations.get_organization()
example = aws.ec2.AmiLaunchPermission("example",
    image_id="ami-12345678",
    organization_arn=current.arn)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/organizations"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := organizations.LookupOrganization(ctx, map[string]interface{}{}, nil)
		if err != nil {
			return err
		}
		_, err = ec2.NewAmiLaunchPermission(ctx, "example", &ec2.AmiLaunchPermissionArgs{
			ImageId:         pulumi.String("ami-12345678"),
			OrganizationArn: pulumi.String(current.Arn),
		})
		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 current = Aws.Organizations.GetOrganization.Invoke();

    var example = new Aws.Ec2.AmiLaunchPermission("example", new()
    {
        ImageId = "ami-12345678",
        OrganizationArn = current.Apply(getOrganizationResult => getOrganizationResult.Arn),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.organizations.OrganizationsFunctions;
import com.pulumi.aws.ec2.AmiLaunchPermission;
import com.pulumi.aws.ec2.AmiLaunchPermissionArgs;
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 current = OrganizationsFunctions.getOrganization(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference);

        var example = new AmiLaunchPermission("example", AmiLaunchPermissionArgs.builder()
            .imageId("ami-12345678")
            .organizationArn(current.arn())
            .build());

    }
}
resources:
  example:
    type: aws:ec2:AmiLaunchPermission
    properties:
      imageId: ami-12345678
      organizationArn: ${current.arn}
variables:
  current:
    fn::invoke:
      function: aws:organizations:getOrganization
      arguments: {}

The organizationArn property grants launch permission to all accounts in your AWS Organization. The getOrganization data source retrieves your organization’s ARN dynamically.

Beyond these examples

These snippets focus on specific launch permission features: account-specific permissions, public access grants, and organization-wide sharing. They’re intentionally minimal rather than complete AMI distribution workflows.

The examples require pre-existing infrastructure such as an AMI that you own in the current region, and an AWS Organization for organization-based sharing. They focus on granting permissions rather than AMI creation or lifecycle management.

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

  • Organizational unit-specific permissions (organizationalUnitArn)
  • Region-specific configuration (region property)
  • Permission removal or revocation workflows

These omissions are intentional: the goal is to illustrate how each permission type is wired, not provide drop-in AMI distribution modules. See the AMI Launch Permission resource reference for all available configuration options.

Let's configure AWS AMI Launch Permissions

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Permission Types & Configuration
How do I make my AMI publicly accessible?
Set group to "all" to grant public launch permissions. This is the only valid value for the group parameter.
How do I grant launch permission to a specific AWS account?
Use the accountId parameter with the target AWS account ID (e.g., "123456789012").
How do I grant launch permission to my entire AWS organization?
Use the organizationArn parameter with your organization’s ARN. You can also use organizationalUnitArn to grant access to a specific organizational unit.
Can I grant multiple types of permissions with a single resource?
No, each resource grants one type of permission. Create separate AmiLaunchPermission resources for each account, organization, or public access grant.
Immutability & Modifications
Can I modify permissions after creating them?
No, all permission properties (accountId, group, organizationArn, organizationalUnitArn, and imageId) are immutable. To change permissions, you must delete and recreate the resource.

Using a different cloud?

Explore security guides for other cloud providers: