

# Publishing extensions to make them available for public use
<a name="publish-extension"></a>

After you've developed and registered a private extension, you can make it publicly available to general CloudFormation users by *publishing* it to the CloudFormation registry, as a third-party public extension.

Public third-party extensions enable you to offer CloudFormation users ways to model, provision, and configure environments containing AWS and third-party resources. As with private extensions, public extensions are treated the same as any resource published by Amazon within CloudFormation; users can use CloudFormation capabilities to create, provision, and manage the extensions you provide in a safe and repeatable manner, just as they would any AWS resource. This includes CloudFormation management capabilities such as change sets, drift detection, and resource import.

Extensions published to the registry are visible by all CloudFormation users in the Regions in which they're published. Users can then *activate* your extension in their account, which makes it available for use in their templates. For more information, see [Using public extensions in CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry-public.html) in the *CloudFormation User Guide*.

**Note**  
If your public extension implements event handlers, users of the extension may incur charges to their account. For example, suppose your public extension is a resource type with create, read, update, list, and delete handlers. Users using your extension in their stacks would incur charges when your handler code executes during the various resource create, read, update, list, and delete stack operations. This is in addition to any charges incurred for the resources themselves running.  
For more information, see [CloudFormation pricing](https://aws.amazon.com/cloudformation/pricing/).

## Developing a public extension for CloudFormation
<a name="publish-extension-overview"></a>

To develop a public third-party extension, develop your extension as a private extension. Then, in each Region in which you want to make the extension publicly available: 

1. [Register your extension](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-register.html) as a private extension in the CloudFormation registry.

1. [Test your extension](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/publish-extension.html#publish-extension-testing) to make sure it meets all necessary requirements for being published in the CloudFormation registry.

1. [Publish your extension](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/publish-extension.html#publish-extension-publishing) to the CloudFormation registry.
**Note**  
Before you publish any extension in a given Region, you must first register as an extension publisher in that Region.  
To complete this in multiple Regions simultaneously, see [Publishing extensions in multiple Regions using StackSets](publish-extension-stacksets.md).

## Prerequisite: Registering your account to publish CloudFormation extensions
<a name="publish-extension-prereqs"></a>

To publish third-party extensions, register your extension publisher with CloudFormation. To do so, you must have an account with one of the following services. CloudFormation uses these services to verify your public identity as a publisher:
+ [AWS Marketplace](https://aws.amazon.com/marketplace/partners/management-tour)
+ [Bitbucket](https://bitbucket.org/)
+ [GitHub](https://github.com/)
**Note**  
CloudFormation doesn't currently support GitHub Enterprise Cloud or GitHub Enterprise Server accounts for identity verification.

If you use your Bitbucket or GitHub account, you must create a connection between that account and the AWS account which you want to register as a publisher. For more information, see the following topics in the *Developer Tools Console User Guide*:
+ [Create a connection to Bitbucket](https://docs.aws.amazon.com/dtconsole/latest/userguide/connections-create-bitbucket.html)
+ [Create a connection to GitHub](https://docs.aws.amazon.com/dtconsole/latest/userguide/connections-create-github.html)

Use [RegisterPublisher](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_RegisterPublisher.html) to register your account to publish extensions. As part of registering as a publisher, you must accept the **[Terms and Conditions](https://cloudformation-registry-documents.s3.amazonaws.com/Terms_and_Conditions_for_AWS_CloudFormation_Registry_Publishers.pdf)** for extension publishers. If you use a Bitbucket or GitHub account for identity verification, you'll need to supply CloudFormation the Amazon Resource Name (ARN) for your connection to that account.

In addition, you'll need the following permissions:
+ `codestar-connections:GetConnection`
+ `codestar-connections:UseConnection`

For more information, see [AWS CodeConnections permissions reference](https://docs.aws.amazon.com/dtconsole/latest/userguide/security-iam.html#permissions-reference-connections) in the *Developer Tools console User Guide*.

When you register, CloudFormation assigns your account a publisher ID under which your extensions will be published. This publisher ID applies across all AWS Regions.

## Testing your public extension before publishing
<a name="publish-extension-testing"></a>

To publish your public extension, it must pass all test requirements defined for it:
+ For resource types, this includes passing all contracts tests defined for the type. For more information about testing resource types, see [Testing resource types using contract tests](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-test.html).
+ For modules, this includes determining if the module's model meets all necessary requirements. For information about publication requirements for modules, see [Requirements for publishing a public module](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/modules-structure.html#modules-structure-publishing-prereqs).
+ For Hooks, this includes determining if the Hook meets all the necessary requirements. For information about publication requirements for Hooks, see [Testing registered Hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-publishing.html#hooks-testing-registered-hooks).

Use [TestType](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_TestType.html) to have CloudFormation perform the required tests on an extension. After running the test, CloudFormation assigns a test status to the extension. An extension must have a test status of `PASSED` in a given Region before it can be published there.

If you don't specify a version, CloudFormation uses the default version of the extension in your account and Region for testing.

Because testing may take some time, `TestType` is an asynchronous operation. Once you've initiated testing on an extension using `TestType`, you can use [DescribeType](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeType.html) to monitor the current test status and test status description for the extension.

The tests that CloudFormation runs against your extension are non-exhaustive and generic, which means that you should also thoroughly test your extension to ensure that it performs as expected. Using your privately registered extension in stack templates is the CloudFormation equivalent of testing your extension in a sandbox environment. Publishing your extension doesn't change any provisioning behavior of your extension; it only makes it available to all customers in the Region in which the extension is published.

## Publishing your public extension to the CloudFormation registry
<a name="publish-extension-publishing"></a>

After your extension has passed all necessary test requirements, you can publish it to make it publicly available for use through the CloudFormation registry. Publishing your extension makes it available in all AWS accounts in the Region. Use `[PublishType](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_PublishType.html)` to publish your extension in each desired Region.

### Versioning your public extension
<a name="publish-extension-version"></a>

When publishing your extension, you can specify a public version number. This is separate and distinct from the private extension version that CloudFormation assigns to a private extension when you register it. If you don't specify a version number, CloudFormation increments the version number by one minor version release.

Use the following format, and adhere to semantic versioning when assigning a version number to your extension:

`MAJOR.MINOR.PATCH`

For more information, see [Semantic Versioning 2.0.0](https://semver.org/).

#### Versioning and updating activated public extensions
<a name="publish-extension-version-auto"></a>

When a user activates a public extension for use in their account, they have the option to have CloudFormation automatically update to using a new minor version whenever one is released by the extension publisher. This only applies to *minor* version changes, including patches. For major version changes, users are required to manually update to a new major version of an extension.

Increment to a new major version if the new version possibly contains breaking changes.

### Open-sourcing your public extension project
<a name="publish-extension-opensource"></a>

It's considered a best practice to open-source your public extensions.

# Publishing extensions in multiple Regions using StackSets
<a name="publish-extension-stacksets"></a>

Because CloudFormation is a regional service, you must repeat each required step to publish your extension to the public registry in all Regions you would like your extension to be available in. However, with the use of CloudFormation resources, you can use AWS CloudFormation StackSets to publish your extensions globally in fewer steps.

For more information about AWS CloudFormation StackSets, see [Working with AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) in the *AWS CloudFormation User Guide*.

## Prerequisites for using AWS CloudFormation StackSets
<a name="publish-extension-stacksets-prereqs"></a>

Before using StackSets, you must complete prerequisites depending on which management policy you want to use for your stack sets.
+ Stack sets with self-managed permissions require that you create IAM roles in the necessary admin and target accounts. If you intend to publish a type across multiple Regions from the same publisher account, you should create the roles in the same account.
+ Stack sets with service-managed permissions make use of AWS Organizations and thus require that you enable trusted access to AWS Organizations.

For detailed instructions to set up the required permissions, see [Prerequisites for stack set operations](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-prereqs.html).

## Using StackSets to publish in multiple Regions for the first time
<a name="publish-extension-stacksets-new"></a>

The example templates in this section publish extensions for the first time to the public registry. They contain the following CloudFormation resource types to mimic the workflow of publishing an extension in a single Region:
+ `AWS::CloudFormation::ResourceVersion` or `AWS::CloudFormation::ModuleVersion` – Registers a new version for a private type.
+ `AWS::CloudFormation::ResourceDefaultVersion` or `AWS::CloudFormation::ModuleDefaultVersion` – Sets the new version to the type’s default version. The default version is used for publishing.
+ `AWS::CloudFormation::Publisher` – Registers the calling account as a publisher with AWS Marketplace. This functionality is idempotent, meaning that once you’ve registered as a publisher, this resource doesn't get updated.
+ `AWS::CloudFormation::PublicTypeVersion` – Tests the new version and publishes it to the public registry.

For more details about each type, including settings you can modify, see the [AWS CloudFormation resource type reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_CloudFormation.html) in the *AWS CloudFormation User Guide*.

**Note**  
The same publishing restrictions apply when you use StackSets to publish extensions globally, including agreeing to the [Terms and Conditions for AWS CloudFormation Registry Publishers](https://cloudformation-registry-documents.s3.amazonaws.com/Terms_and_Conditions_for_AWS_CloudFormation_Registry_Publishers.pdf) before registering as a publisher and ensuring your extension passes all test requirements before successfully publishing.

The following example template publishes a resource type across Regions with StackSets.

```
AWSTemplateFormatVersion: "2010-09-09"
Description: Registers and sets a new default resource version, registers the account as a publisher, and publishes the resource to the public registry.
Parameters:
  SchemaPackageURL:
    Description: URL to S3::Bucket that contains the resource project package 
    Type: String
Resources:
  PrivateResourceVersion: 
    Type: AWS::CloudFormation::ResourceVersion
    Properties:
      SchemaHandlerPackage: !Ref SchemaPackageURL 
      TypeName: MyOrg::MyService::MyType 
  ResourceDefaultVersion:    
    Type: AWS::CloudFormation::ResourceDefaultVersion
    DependsOn: PrivateResourceVersion
    Properties:
      TypeVersionArn: !Ref PrivateResourceVersion
  Publisher:
    Type: AWS::CloudFormation::Publisher
    DependsOn: ResourceDefaultVersion
    Properties:
      AcceptTermsAndConditions: true
  PublishedResource:     
    Type: AWS::CloudFormation::PublicTypeVersion
    DependsOn: Publisher
    Properties:
      Type: RESOURCE
      TypeName: MyOrg::MyService::MyType
```

The following example template publishes a module across Regions with StackSets.

```
AWSTemplateFormatVersion: "2010-09-09"
Description: Registers and sets a new default module version, registers the account as a publisher, and publishes the module to the public registry with the given public version.
Parameters:
  VersionToPublish:
    Description: Version number for published version, e.g. 1.2.3
    Type: String
    Default: AWS::NoValue
  FirstTimePublishing:
    Description: Indicate if this is the first time publishing this extension in the targeted region. 
    Type: String
    AllowedValues:
      - true
      - false
  SchemaPackageURL:
    Description: URL to S3::Bucket that contains the resource project package 
    Type: String
Conditions:
  IsFirstTimePublishing: !Equals
    - !Ref FirstTimePublishing
    - true    
Resources:
  PrivateModuleVersion:
    Type: AWS::CloudFormation::ModuleVersion
    Properties:
      ModulePackage: !Ref SchemaPackageURL 
      ModuleName: MyOrg::MyService::MyType::MODULE 
  ModuleDefaultVersion:    
    Type: AWS::CloudFormation::ModuleDefaultVersion 
    DependsOn: PrivateModuleVersion
    Properties:
      Arn: !Ref PrivateModuleVersion
  Publisher:
    Type: AWS::CloudFormation::Publisher
    DependsOn: ModuleDefaultVersion
    Properties:
      AcceptTermsAndConditions: true
  PublishedModule:      
    Type: AWS::CloudFormation::PublicTypeVersion
    DependsOn: Publisher
    Properties:
      Type: MODULE 
      TypeName: MyOrg::MyService::MyType::MODULE      
      PublicVersionNumber: 
        Fn::If:
        - IsFirstTimePublishing
        - Ref: AWS::NoValue
        - Ref: VersionToPublish
```

Note that for `AWS::CloudFormation::PublicTypeVersion` resources, `PublicVersionNumber` can't be specified upon creation. CloudFormation automatically publishes the first version of the extension with version number 1.0.0.

As a publisher, you can choose to provide version numbers for new versions. The second template above requires you to input whether it's your first time publishing the extension. You can subsequently modify this by overriding parameters when updating the stack set.

If you instead choose to omit the `PublicVersionNumber` property (as shown in the first template above), all publishing updates increment the minor version by 1. For example, version 1.0.0 increments to version 1.1.0. To publish a new patch or major version, you must explicitly specify a new version number.

Once your template is created and validated, you can create a stack set and new stack instances for each Region you want to publish your extension in. For more information about how to use AWS CloudFormation StackSets in the AWS CLI and AWS Management Console, see [Create a stack set](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-getting-started-create.html) in the *AWS CloudFormation User Guide*.

## Using StackSets to update already published extensions
<a name="publish-extension-stacksets-update"></a>

AWS CloudFormation StackSets allows you to customize each stack instance, meaning that you can use the same stack set to continuously update and maintain your published extensions. If you’ve already published extensions to the public registry and want to use StackSets to manage all future updates, you can bring them directly into the stack set *without* publishing a new version.
+ If the extensions were registered, tested, and published using CloudFormation APIs, they first need to be imported into stacks. For information about using resource import, see [Bringing existing resources into CloudFormation management](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import.html).
+ If the extensions were managed in individual stacks or you’ve successfully imported them into stacks, the stacks need to be imported into the stack set. For instructions, see [Importing a stack into AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-import.html).

You can use the following StackSets actions to update your published extensions:
+ [Adding stack instances](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stackinstances-create.html) to your stack set publishes your extensions in additional Regions. If you add a stack instance in a Region you’ve already independently published to (not using StackSets), this brings the published extension into the stack set’s management.
+ [Overriding parameters on existing stack instances](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stackinstances-override.html) allows you to update and publish new versions for your already published extensions at an individual level. This can be used when you want to specify new version numbers when performing updates.
+ [Updating your stack set](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-update.html) can be used to modify the existing template, add new stack instances, modify parameters, and perform other edits. You can do this if you choose not to specify version numbers in your template, but later decide you want to provide them.

For more information about how to use AWS CloudFormation StackSets, see [Working with AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) in the *AWS CloudFormation User Guide*.