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, organizations, or the public. This guide focuses on three capabilities: account-specific sharing, public distribution, and organization-wide access.

Launch permissions control who can use your AMI to launch EC2 instances. You must own the AMI in the current region. The examples are intentionally small. Combine them with your own AMI creation workflow and access control requirements.

Grant launch permission to a specific AWS account

Teams sharing AMIs across AWS accounts grant launch permissions to specific account IDs, allowing partners or subsidiaries to launch instances without making the AMI public.

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 receives launch permission. This creates a one-to-one permission; repeat this resource for each account that needs access.

Make an AMI publicly launchable

Open-source projects or public tools distribute AMIs that anyone can launch by setting the group to “all”.

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

The group property with value “all” makes the AMI launchable by any AWS account globally. This is the only valid group value; it grants unrestricted public access to your AMI.

Share an AMI across an AWS Organization

Large enterprises with AWS Organizations grant launch permissions to all member accounts without listing each individually.

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, &organizations.LookupOrganizationArgs{}, 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.organizations.inputs.GetOrganizationArgs;
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(GetOrganizationArgs.builder()
            .build());

        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 every account in your AWS Organization. The getOrganization data source retrieves your organization’s ARN dynamically. This scales automatically as accounts join or leave the organization.

Beyond these examples

These snippets focus on specific launch permission features: account-specific sharing, public distribution, and organization-wide access. They’re intentionally minimal rather than full 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 management.

To keep things focused, common AMI sharing patterns are omitted, including:

  • Organizational unit sharing (organizationalUnitArn)
  • Cross-region AMI sharing workflows
  • AMI creation and ownership verification
  • Revoking permissions (requires resource deletion)

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
What types of launch permissions can I grant for an AMI?

You can grant four types of launch permissions:

  1. Specific account - Use accountId with an AWS account ID
  2. Public access - Use group set to "all"
  3. Organization - Use organizationArn with an organization ARN
  4. Organizational unit - Use organizationalUnitArn with an OU ARN
How do I make my AMI publicly accessible?
Set the group property to "all". This is the only valid value for the group field and grants launch permission to all AWS accounts.
Can I grant multiple types of permissions with a single resource?
No, each AmiLaunchPermission resource grants one permission type. To grant multiple permissions, create separate resources for each account, organization, or group.
Immutability & Limitations
Can I change who has access to my AMI after creating the permission?
No, all permission fields (accountId, group, organizationArn, organizationalUnitArn) are immutable. Changing any of these requires destroying and recreating the resource.
Can I change the AMI that a launch permission applies to?
No, the imageId property is immutable. To grant permissions for a different AMI, create a new AmiLaunchPermission resource.

Using a different cloud?

Explore security guides for other cloud providers: