

# Add CloudFormation templates to your product
Add CloudFormation templates to your product

AWS Marketplace sellers can list AMI-based products that are delivered to AWS Marketplace buyers by using AWS CloudFormation templates. Adding a CloudFormation template to your AMI-based product allows your buyers to deploy your solution without having to manually configure the resources and dependencies. You can use the templates to define a cluster or distributed architecture for the products or to select different AMI combinations or product configurations. Single AMI solutions can contain a maximum of three CloudFormation templates.

The CloudFormation templates can be configured to deliver a single Amazon Machine Image (AMI) with associated configuration files and Lambda functions. Additionally, you must include an architectural diagram for each template.

**Topics**
+ [

## Preparing your CloudFormation template
](#aws-cloudformation-template-preparation)
+ [

## Architectural diagram
](#topology-diagram)
+ [

## Convert CloudFormation templates of existing products
](#convert-cloudformation-templates)
+ [

# Adding serverless application components
](cloudformation-serverless-application.md)

## Preparing your CloudFormation template


To build your CloudFormation templates, you must meet the template prerequisites and provide the required input and security parameters. When submitting your CloudFormation template, use the guidelines in the following sections.

### Template prerequisites

+ Verify that the template is launched successfully through the CloudFormation console **in all AWS Regions enabled for your product**. You can use the [TaskCat tool](https://github.com/aws-quickstart/taskcat) to test your templates.
+ AMIs included in your CloudFormation template must either be the AMI of the product you are publishing or an AWS-managed AMI such as the latest Amazon Linux 2. Don't include any community AMI or AMI owned and shared by you or any other third-party. To use an AWS-managed AMI, use [public parameters in AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-public-parameters.html) instead of hardcoding AMI IDs. For example, within your CloudFormation template where you specify the AMI ID, you use a dynamic reference `ImageId: '{{resolve:ssm:/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id}}'`.
+ Build templates so that they do not depend on the use in a particular Availability Zone (AZ). Not all customers have access to all AZs, and AZs are mapped differently for different accounts.
+ If you're building a clustered solution using an Auto Scaling group, we recommend that you account for a scaling event. The new node should join the running cluster automatically.
+ Even for single-node products, we recommend using an [Auto Scaling group](https://docs.aws.amazon.com/autoscaling/latest/userguide/create-asg-from-instance.html).
+ If your solution involves a cluster of multiple instances, consider using placement groups if you want low network latency, high network throughput, or both among the instances.
+ For ease of review by the AWS Marketplace team and transparency to the customer, we recommend that you add comments in your **UserData** section.

### Requirements for AMI details


**Note**  
If you create an **Amazon Machine Image (AMI) or AMI with CloudFormation** on the [server products](https://aws.amazon.com//marketplace/management/products/server) page of the seller portal and are prompted to download the [product load form](https://docs.aws.amazon.com//marketplace/latest/userguide/product-submission.html#aws-cloudformation-launched-product-free-or-paid-or-usage-based-paid-ami-product), see [Requirements for AMI details using the product load form](#ami-requirements-product-load-form) instead.

When specifying the `ImageId` property of resources that deploy your AMI to EC2 instances such as [AWS::EC2::Instance](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-resource-ec2-instance.html), [AWS::AutoScaling::LaunchConfiguration](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-launchconfiguration.html), and [AWS::EC2::LaunchTemplate](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html) resources, you must reference a [template parameter.](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) The parameter type must be either a `AWS::EC2::Image::Id`, `AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>`, or `String`.

You can name this template parameter any valid parameter name. AWS Marketplace copies your template to its own Amazon S3 buckets and replaces the specified parameter with an [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com//systems-manager/latest/userguide/systems-manager-parameter-store.html) parameter. AWS Marketplace also updates the description and constraint text to make the correct value clear to buyers who are deploying the template. When buyers deploy your template, that parameter resolves to the AWS Region-specific AMI ID of your published product.

The following template examples illustrate the `ImageId` property referencing template parameters using the intrinsic function [Ref](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html).

YAML example:

```
Parameters:
  ImageId:
    Type: AWS::EC2::Image::Id
    Default: ami-example1234567890
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref ImageId
```

JSON example:

```
{
  "Parameters": {
    "ImageId": {
      "Type": "AWS::EC2::Image::Id",
      "Default": "ami-example1234567890"
    }
  },
  "Resources": {
    "MyInstance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": {
          "Ref": "ImageId"
        }
      }
    }
  }
}
```

If you are deploying EC2 instances inside a [nested stack](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html) instead of the root stack, the AMI ID must dynamically inherit its value from the root stack. Edit your root and nested stacks so that in the root stack, setting the value of your template parameter overrides the AMI ID used in this nested stack.

### Requirements for AMI details using the product load form


**Note**  
When you create an **Amazon Machine Image (AMI) or AMI with CloudFormation** on the [server products](https://aws.amazon.com//marketplace/management/products/server) page of the seller portal and are not immediately prompted to download the [product load form](https://docs.aws.amazon.com//marketplace/latest/userguide/product-submission.html#aws-cloudformation-launched-product-free-or-paid-or-usage-based-paid-ami-product), see [Requirements for AMI details](#ami-requirements-sse) instead.

AMIs must be in a mapping table for each Region. The AWS Marketplace team updates the AMI IDs after they're cloned. Your source AMI must be in the `us-east-1` Region. The other Regions can use placeholders.

YAML example:

```
Mappings: 
  RegionMap: 
      us-east-1: 
          ImageId: ami-0123456789abcdef0
      us-west-1: 
          ImageId: ami-xxxxxxxxxxxxxxxxx
      eu-west-1: 
          ImageId: ami-xxxxxxxxxxxxxxxxx
      ap-southeast-1: 
          ImageId: ami-xxxxxxxxxxxxxxxxx
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap 
        - RegionMap
        - !Ref AWS::Region
        - ImageId
```

### Requirements for nested stack templates


**Note**  
This section only applies to pricing models that do not use the [product load form](https://docs.aws.amazon.com//marketplace/latest/userguide/product-submission.html#aws-cloudformation-launched-product-free-or-paid-or-usage-based-paid-ami-product). For pricing models that *do use* the product load form, only a fixed string is allowed for the nested stack `TemplateURL` property.

If your template includes [nested stacks](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html), the `TemplateURL` property of nested stack resources must reference the template parameters for the Amazon S3 bucket name, bucket Region, and Amazon S3 object key prefix. The parameter names for the bucket name must be `MPS3BucketName`, the bucket Region must be `MPS3BucketRegion`, and for the object key prefix must be `MPS3KeyPrefix`.

Set the default values for these parameters to correspond to your Amazon S3 bucket where your nested templates are stored. All nested templates must be publicly accessible. When you submit your template for publishing, AWS Marketplace copies your templates to its own Amazon S3 buckets and modifies the properties of those three parameters to have the default value and allowed value set to correspond with where the copies are stored. AWS Marketplace also updates the description and constraint text to make the correct values clear to buyers who are deploying the template.

If you have multiple levels of nested stacks, all nested stacks that create additional nested stacks must be configured so that the `TemplateURL` property dynamically inherits the values of the Amazon S3 bucket name, Amazon S3 bucket Region, and Amazon S3 object key from the root stack. Edit your root and nested stacks so that in the root stack, setting the value of the template parameter `MPS3BucketName`, `MPS3BucketRegion`, and `MPS3KeyPrefix` overrides their respective values in the URL used in this nested stack to create additional nested stacks.

The following template examples illustrate the `TemplateURL` property referencing template parameters using the intrinsic function [Fn::Sub](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html).

YAML example:

```
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: AWS Marketplace Parameters
        Parameters:
          - ImageId
          - MPS3BucketName
          - MPS3BucketRegion
          - MPS3KeyPrefix
Parameters:
  ImageId:
    Type: AWS::EC2::Image::Id
    Default: ami-example1234567890
    Description: The AMI that will be used to launch EC2 resources.
  MPS3BucketName:
    Type: String
    Default: sellerbucket
    Description: Name of the S3 bucket for your copy of the nested templates.
  MPS3BucketRegion:
    Type: String
    Default: us-east-1
    Description: AWS Region where the S3 bucket for your copy of the nested templates is hosted.
  MPS3KeyPrefix:
    Type: String
    Default: sellerproductfolder/
    Description: S3 key prefix that is used to simulate a folder for your copy of the nested templates.
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref ImageId
  NestedStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub https://${MPS3BucketName}.s3.${MPS3BucketRegion}.${AWS::URLSuffix}/${MPS3KeyPrefix}nested-template.yaml
```

JSON example:

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Metadata": {
        "AWS::CloudFormation::Interface": {
            "ParameterGroups": [
                {
                    "Label": {
                        "default": "AWS Marketplace Parameters"
                    },
                    "Parameters": [
                        "ImageId",
                        "MPS3BucketName",
                        "MPS3BucketRegion",
                        "MPS3KeyPrefix"
                    ]
                }
            ]
        }
    },
    "Parameters": {
        "ImageId": {
            "Type": "AWS::EC2::Image::Id",
            "Default": "ami-example1234567890",
            "Description": "The AMI that will be used to launch EC2 resources."
        },
        "MPS3BucketName": {
            "Type": "String",
            "Default": "sellerbucket",
            "Description": "Name of the S3 bucket for your copy of the nested templates."
        },
        "MPS3BucketRegion": {
            "Type": "String",
            "Default": "us-east-1",
            "Description": "AWS Region where the S3 bucket for your copy of the nested templates is hosted."
        },
        "MPS3KeyPrefix": {
            "Type": "String",
            "Default": "sellerproductfolder/",
            "Description": "S3 key prefix that is used to simulate a folder for your copy of the nested templates."
        }
    },
    "Resources": {
        "EC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": {
                    "Ref": "ImageId"
                }
            }
        },
        "NestedStack": {
            "Type": "AWS::CloudFormation::Stack",
            "Properties": {
                "TemplateURL": {
                    "Fn::Sub": "https://${MPS3BucketName}.s3.${MPS3BucketRegion}.${AWS::URLSuffix}/${MPS3KeyPrefix}nested-template.yaml"
                }
            }
        }
    }
}
```

**Note**  
[AWS::CloudFormation::Interface](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html) is used to define how parameters are grouped and sorted in the AWS CloudFormation console when buyers deploy your template.

### Template input parameters

+ Input parameters to the template must not include the AWS Marketplace customer's AWS credentials (such as passwords, public keys, private keys, or certificates).
+ For sensitive input parameters such as passwords, choose the `NoEcho` property and enable stronger regular expression. For other input parameters, set the most common inputs along with appropriate helper text.
+ Use CloudFormation parameter types for inputs where available.
+ Use `AWS::CloudFormation::Interface` to group and sort input parameters.
+ Don't set any default values for the following input parameters:
**Note**  
Customers must provide these as input parameters.
  + Default CIDR ranges that allow ingress into remote access ports from the public internet
  + Default CIDR ranges that allow ingress into database connection ports from the public internet
  + Default passwords for users or databases

### Network and security parameters

+ Ensure that the default SSH port (22) or RDP port (3389) isn't open to 0.0.0.0.
+ Instead of using the default virtual private cloud (VPC), we recommend that you build a VPC with appropriate access control lists (ACLs) and security groups. 
+ Your template can't request long-term access keys from users or create them to access AWS resources. If your AMI application requires access to the AWS services in the buyer’s account, it must use [IAM roles for Amazon EC2](/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html).
+ Set IAM roles and policies to [grant the least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) and enable write access only when absolutely necessary. For example, if your application needs only `S3:GET`, `PUT`, and `DELETE` operations, specify those actions only. We don't recommend the use of `S3:*` in this case. 

After your template is received, AWS Marketplace validates the product configuration and information and provides feedback for any required revisions.

## Architectural diagram


You must provide an architectural diagram for each template. To learn more about diagramming, see [What is architecture diagramming?](https://aws.amazon.com/what-is/architecture-diagramming/)

The diagram must meet the following criteria:
+ Illustrate a standard deployment on AWS.
+ Depict logically where resources are deployed. For example, resources like Amazon EC2 instances are in the correct subnet.
+ Use the most current AWS product icons for each AWS service deployed through the CloudFormation template. To download the current set of architecture icons, see [AWS Architecture Icons](https://aws.amazon.com/architecture/icons/).
+ Include metadata for all the services deployed by the CloudFormation template.
+ Include all networks, VPCs, and subnets deployed by the CloudFormation template.
+ Show integration points, including third party assets, APIs and on-premises, hybrid assets.
+ Diagrams must be 1100 x 700 pixels in size. Maintain original diagram proportions without stretching or cropping.

## Convert CloudFormation templates of existing products


**Note**  
This section is for sellers with an existing AMI with CloudFormation product that used the [product load form](https://docs.aws.amazon.com/marketplace/latest/userguide/product-submission.html#aws-cloudformation-launched-product-free-or-paid-or-usage-based-paid-ami-product) to publish their templates and now want to update that template without using the product load form. If you are publishing a new product, see [Preparing your CloudFormation templates](https://docs.aws.amazon.com/marketplace/latest/userguide/cloudformation.html#aws-cloudformation-template-preparation).  
If you create an **Amazon Machine Image (AMI) or AMI with CloudFormation** on the [server products](https://aws.amazon.com//marketplace/management/products/server) page of the seller portal and are prompted to download the [product load form](https://docs.aws.amazon.com//marketplace/latest/userguide/product-submission.html#aws-cloudformation-launched-product-free-or-paid-or-usage-based-paid-ami-product), see [Requirements for AMI details using the product load form](#ami-requirements-product-load-form).

If you want to use the self-service experience to update an existing product that previously used the [product load form](https://docs.aws.amazon.com/marketplace/latest/userguide/product-submission.html#aws-cloudformation-launched-product-free-or-paid-or-usage-based-paid-ami-product) to publish, you must make changes to your existing CloudFormation template.

The following table describes the difference between using the product load form and the self-service experience:


****  

|  | Product load form | Self-service experience | 
| --- | --- | --- | 
| Value of ImageId property for EC2 resources | References a mapping table for your AMI ID. For more information, see [Requirements for AMI details using the product load form](#ami-requirements-product-load-form).  | References a template parameter for your AMI ID. For more information, see [Requirements for AMI details](#ami-requirements-sse).  | 
| Value of TemplateURL property for nested stacks | Must be a fixed string and can't use intrinsic functions. | Can be dynamic by using intrinsic functions. Must reference a set of template parameters. For more information, see [Requirements for nested stack templates](#nested-stack-template-requirements) | 

The following example templates illustrate an example of an existing product that used the product load form to publish the template. In this example, the AMI ID is `ami-example123456` and a nested template is in a seller’s S3 bucket at the location `https://sellerbucket.s3.us-east-1.amazonaws.com/sellerproductfolder/nested-template.yaml`.

YAML example published with the product load form:

```
AWSTemplateFormatVersion: '2010-09-09'
Mappings:
  RegionMap:
    us-east-1:
      AMI: ami-example123456
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap 
        - RegionMap
        - !Ref AWS::Region
        - AMI
  NestedStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://sellerbucket.s3.us-east-1.amazonaws.com/sellerproductfolder/nested-template.yaml
```

JSON example published with the product load form:

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Mappings": {
        "RegionMap": {
            "us-east-1": {
                "AMI": "ami-example123456"
            }
        }
    },
    "Resources": {
        "EC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": {
                    "Fn::FindInMap": [
                        "RegionMap",
                        {
                            "Ref": "AWS::Region"
                        },
                        "AMI"
                    ]
                }
            }
        },
        "NestedStack": {
            "Type": "AWS::CloudFormation::Stack",
            "Properties": {
                "TemplateURL": "https://sellerbucket.s3.us-east-1.amazonaws.com/sellerproductfolder/nested-template.yaml"
            }
        }
    }
}
```

The following template examples illustrate the changes required to use the self-service experience to update the product.

YAML example published with the self-service experience:

```
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: AWS Marketplace Parameters
        Parameters:
          - ImageId
          - MPS3BucketName
          - MPS3BucketRegion
          - MPS3KeyPrefix
Parameters:
  ImageId:
    Type: AWS::EC2::Image::Id
    Default: ami-example123456
    Description: The AMI that will be used to launch EC2 resources.
  MPS3BucketName:
    Type: String
    Default: sellerbucket
    Description: Name of the S3 bucket for your copy of the nested templates.
  MPS3BucketRegion:
    Type: String
    Default: us-east-1
    Description: AWS Region where the S3 bucket for your copy of the nested templates is hosted.
  MPS3KeyPrefix:
    Type: String
    Default: sellerproductfolder/
    Description: S3 key prefix that is used to simulate a folder for your copy of the nested templates.
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref ImageId
  NestedStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub https://${MPS3BucketName}.s3.${MPS3BucketRegion}.${AWS::URLSuffix}/${MPS3KeyPrefix}nested-template.yaml
```

JSON Example published with the self-service experience:

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Metadata": {
        "AWS::CloudFormation::Interface": {
            "ParameterGroups": [
                {
                    "Label": {
                        "default": "AWS Marketplace Parameters"
                    },
                    "Parameters": [
                        "ImageId",
                        "MPS3BucketName",
                        "MPS3BucketRegion",
                        "MPS3KeyPrefix"
                    ]
                }
            ]
        }
    },
    "Parameters": {
        "ImageId": {
            "Type": "AWS::EC2::Image::Id",
            "Default": "ami-example123456",
            "Description": "The AMI that will be used to launch EC2 resources."
        },
        "MPS3BucketName": {
            "Type": "String",
            "Default": "sellerbucket",
            "Description": "Name of the S3 bucket for your copy of the nested templates."
        },
        "MPS3BucketRegion": {
            "Type": "String",
            "Default": "us-east-1",
            "Description": "AWS Region where the S3 bucket for your copy of the nested templates is hosted."
        },
        "MPS3KeyPrefix": {
            "Type": "String",
            "Default": "sellerproductfolder/",
            "Description": "S3 key prefix that is used to simulate a folder for your copy of the nested templates."
        }
    },
    "Resources": {
        "EC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": {
                    "Ref": "ImageId"
                }
            }
        },
        "NestedStack": {
            "Type": "AWS::CloudFormation::Stack",
            "Properties": {
                "TemplateURL": {
                    "Fn::Sub": "https://${MPS3BucketName}.s3.${MPS3BucketRegion}.${AWS::URLSuffix}/${MPS3KeyPrefix}nested-template.yaml"
                }
            }
        }
    }
}
```

# Adding serverless application components
Adding serverless application components

**Important**  
AWS Marketplace no longer supports publishing new products with CloudFormation templates that deploy resources from AWS Serverless Application Repository. Sellers can continue to publish existing products with CloudFormation templates that deploy resources from AWS Serverless Application Repository until a future date to be announced.

You can create a product that includes an Amazon Machine Image (AMI), delivered using a AWS CloudFormation template, with serverless components incorporated into the product. For example, you can create a product with an AMI configured as a controller server and deliver it as a CloudFormation stack. The CloudFormation template used to create the stack can include the definition to set up an AWS Lambda function that is triggered by an event in the server. When you use this approach to design your product, you can simplify the architecture and make it easier for your buyers to launch. This approach can also make it easier for you to update your product. Thes following sections show you how to create and offer this type of product.

For information about creating an AMI for your product, see [AMI-based products in AWS Marketplace](ami-products.md). For information about completing AWS CloudFormation templates for your product, see [Add CloudFormation templates to your product](cloudformation.md). 

When you define your serverless application, you use an AWS Serverless Application Model (AWS SAM) template that you store in the AWS Serverless Application Repository. AWS SAM is an open-source framework for building serverless applications. During deployment, AWS SAM transforms and expands the AWS Serverless Application Model syntax into CloudFormation syntax. The AWS Serverless Application Repository is a managed repository for serverless applications. It makes it possible for you to store and share reusable applications so buyers can assemble and deploy serverless architectures. 

**Note**  
AWS Marketplace reviews and validates your product before your listing is created. If there are issues you must resolve before the offer is listed, we will send you an email message.
As part of fulfilling a subscription, we copy the AMIs, serverless applications, and CloudFormation templates to an AWS Marketplace-owned repository in each AWS Region. When a buyer subscribes to your product, we give them access, and also notify them when you update your software.

**Topics**
+ [

## Step 1: Create a serverless application
](#cloudformation-serverless-application-procedure-step-1)
+ [

## Step 2: Publish your application to the repository
](#cloudformation-serverless-application-procedure-step-2)
+ [

## Step 3: Create the CloudFormation template
](#cloudformation-serverless-application-procedure-step-3)
+ [

## Step 4: Submit your CloudFormation template and configuration files
](#cloudformation-serverless-application-procedure-step-4)
+ [

## Step 5: Update your AWS Serverless Application Repository application permissions
](#cloudformation-serverless-application-procedure-step-5)
+ [

## Step 6: Share your AMI
](#cloudformation-serverless-application-procedure-step-6)
+ [

## Step 7: Submit your CloudFormation product with AMI and serverless application
](#cloudformation-serverless-application-procedure-step-7)

## Step 1: Create a serverless application


Your first step is to package the AWS Lambda functions used to create your serverless application. Your application is a combination of Lambda functions, event sources, and other resources that work together to perform tasks. A serverless application can be as simple as one Lambda function, or it can contain multiple functions with other resources, such as APIs, databases, and event source mappings.

Use the AWS SAM to define a model for your serverless application. For descriptions of property names and types, see [AWS::Serverless::Application](https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapplication) in AWSLabs on GitHub. The following is an example of an AWS SAM template with a single Lambda function and AWS Identity and Access Management (IAM) role.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An example of SAM template with Lambda function and IAM role

Resources:
  SampleFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: 'com.sampleproject.SampleHandler::handleRequest'
      Runtime: java8
      CodeUri: 's3://amzn-s3-demo-bucket/2EXAMPLE-1234-4b12-ac37-515EXAMPLEe5-lambda.zip'
      Description: Sample Lambda function
      Timeout: 120
      MemorySize: 1024
      Role:
        Fn::GetAtt: [SampleFunctionRole, Arn]

  # Role to execute the Lambda function
  SampleFunctionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
      Policies:
        - PolicyName: SFNXDeployWorkflowDefinitionPolicy
          PolicyDocument:
            Statement:
              - Effect: "Allow"
                Action:
                  - "s3:Get*"
                Resource: "*"
      RoleName: "SampleFunctionRole"
```

## Step 2: Publish your application to the repository


To publish an application, you first upload the application code. Store your code artifacts (for example, Lambda functions, scripts, configuration files) in an Amazon S3 bucket that your account owns. When you upload your application, it's initially set to private, meaning that it's only available to the AWS account that created it. You must create an IAM policy that grants AWS Serverless Application Repository permissions to access the artifacts you uploaded.

**To publish your serverless application to the serverless application repository**

1. Open the Amazon S3 console at [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/).

1. Choose the Amazon S3 bucket that you used to package your application.

1. Choose the **Permissions** tab.

1. Choose **Bucket Policy**.

1. Copy and paste the following example policy statement. 
**Note**  
The example policy statement will produce an error until values for `aws:SourceAccount` and `Resource` are updated in following steps.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service":  "serverlessrepo.amazonaws.com"
               },
               "Action": "s3:GetObject",
               "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
               "Condition" : {
                   "StringEquals": {
                       "aws:SourceAccount": "123456789012"
                   }
               }
           }
       ]
   }
   ```

------

   1. Replace amzn-s3-demo-bucket in the `Resource` property value with the bucket name for your bucket. 

   1. Replace *123456789012* in the `Condition` element with your AWS account ID. The `Condition` element ensures that the AWS Serverless Application Repository only has permission to access applications from the specified AWS account.

1. Choose **Save**.

1. Open the AWS Serverless Application Repository console at [https://console.aws.amazon.com/serverlessrepo](https://console.aws.amazon.com/serverlessrepo).

1. On the **My Applications** page, choose **Publish application**.

1. Complete the required fields and any optional field, as appropriate. The required fields are:
   +  **Application name** 
   +  **Author** 
   +  **Description** 
   +  **Source code URL** 
   +  **SAM template** 

1. Choose **Publish Application**. 

**To publish subsequent versions of your application**

1. Open the AWS Serverless Application Repository console at [https://console.aws.amazon.com/serverlessrepo](https://console.aws.amazon.com/serverlessrepo).

1. In the navigation pane, from **My Applications**, choose the application.

1. Choose **Publish new version**.

For more information, see [Publishing serverless Applications Using the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-publishing-applications.html).

## Step 3: Create the CloudFormation template


To build your CloudFormation templates, you must meet the template prerequisites and provide the required input and security parameters. For more information, see [Template anatomy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html) in the *AWS CloudFormation User Guide*.

In your CloudFormation template, you can reference your serverless application and your AMI. You can also use nested CloudFormation templates and reference serverless applications both in the root template and the nested templates. To reference the serverless application, you use the AWS SAM template. You can automatically generate the AWS SAM template for your application from the AWS Serverless Application Repository. The following is an example template.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An example root template for a SAR application

Resources:
  SampleSARApplication:
    Type: AWS::Serverless::Application
    Properties:
      Location:
         ApplicationId: arn:aws:serverlessrepo:us-east-1:1234567890:applications/TestApplication
         SemanticVersion: 1.0.0
  SampleEC2Instance:
    Type: AWS::EC2::Instance
      Properties: 
        ImageId: "ami-79fd7eee"
        KeyName: "testkey"
        BlockDeviceMappings: 
          - DeviceName: "/dev/sdm"
            Ebs: 
              VolumeType: "io1"
              Iops: "200"
              DeleteOnTermination: "false"
              VolumeSize: "20"
          - DeviceName: "/dev/sdk"
            NoDevice: {}
```

The AWS SAM template contains the following elements:
+  `ApplicationID` – Your application's Amazon Resource Name (ARN). This information is located in the **My Applications** section of the AWS Serverless Application Repository.
+  `SemanticVersion` – The version of your serverless application. You can find this from the **My Applications** section of the AWS Serverless Application Repository.
+  `Parameter` (optional) – Application parameters.

**Note**  
For `ApplicationID` and `SemanticVersion`, [intrinsic functions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) aren't supported. You must hardcode those strings. The `ApplicationID` is updated when it's cloned by AWS Marketplace.

If you're planning to reference configuration and script files in your CloudFormation template, use the following format. For nested templates (`AWS::Cloudformation::Stack`), only `TemplateURLs` without intrinsic functions are supported. Note the `Parameters` content in the template.

```
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
  Name: Seller test product
Parameters:
  CFTRefFilesBucket:
    Type: String
    Default: "seller-bucket"
  CFTRefFilesBucketKeyPrefix:
    Type: String
    Default: "cftsolutionFolder/additionCFfiles"
Resources:
  TestEc2:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        addCloudAccount:
          files:
            /etc/cfn/set-aia-settings.sh:
              source:
                Fn::Sub:
                - https://${CFTRefFilesBucket}.${S3Region}amazonaws.com/${CFTRefFilesBucketKeyPrefix}/sampleScript.sh
                - S3Region:
                    !If
                    - GovCloudCondition
                    - s3-us-gov-west-1
                    - s3
              owner: root
              mode: '000700'
              authentication: Amazon S3AccessCreds
    ..
    ..
    ..
  SampleNestedStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: 'https://sellerbucket.s3.amazon.com/sellerproductfolder/nestedCft.template'
      Parameters:
        SampleParameter: 'test'
Transform: AWS::Serverless-2016-10-31
```

## Step 4: Submit your CloudFormation template and configuration files


To submit your CloudFormation template and configuration and scripts files, grant AWS Marketplace permissions to read the Amazon S3 bucket where these files are stored. To do so, update your bucket policy to include the following permissions.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service":  "assets.marketplace.amazonaws.com"
            },
            "Action": ["s3:GetObject", "s3:ListBucket"],
            "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket",
                         "arn:aws:s3:::amzn-s3-demo-bucket/*"]
        }
    ]
}
```

------

## Step 5: Update your AWS Serverless Application Repository application permissions


To submit your AWS Serverless Application Repository application to AWS Marketplace, you must grant AWS Marketplace permissions to read your application. To do that, add permissions to a policy associated with your serverless application. There are two ways to update your application policy:
+ Go to the [AWS Serverless Application Repository](https://console.aws.amazon.com/serverlessrepo/home). Choose your serverless application from the list. Select the **Sharing** tab, and choose **Create Statement**. On the **Statement configuration** page, enter the following service principal, **assets.marketplace.amazonaws.com**, in the **Account Ids** field. Then choose **Save**.
+ Use the following AWS CLI command to update your application policy.

  ```
  aws serverlessrepo put-application-policy \
  --region region \
  --application-id application-arn \
  --statements Principals=assets.marketplace.amazonaws.com,Actions=Deploy
  ```

## Step 6: Share your AMI


All AMIs built and submitted to AWS Marketplace must adhere to all product policies. Self-service AMI scanning is available in the AWS Marketplace Management Portal. With this feature, you can initiate scans of your AMIs. You receive scanning results quickly (typically, in less than an hour) with clear feedback in a single location. After your AMI has been successfully scanned, submit the AMI for processing by the AWS Marketplace Seller Operations team by uploading your product load form. 

## Step 7: Submit your CloudFormation product with AMI and serverless application


Keep the following in mind before you submit your product:
+ You must provide an architectural diagram for each template. The diagram must use the AWS product icons for each AWS service deployed through the CloudFormation template. Also, the diagram must include metadata for the services. To download our official AWS architecture icons, see [AWS Architecture Icons](https://aws.amazon.com/architecture/icons).
+ The infrastructure cost estimate for each template displayed to buyers is based on an estimate that you provide by using the [AWS Pricing Calculator](https://calculator.s3.amazonaws.com/index.html). In the estimate, include the list of services to be deployed as part of the template, along with the default values for a typical deployment.
+ Complete the product load form. You can find the product load form from the AWS Marketplace Management Portal. A different product load form is required for single AMI products and multiple AMI products. In the product load form, you will provide a public URL to your CloudFormation template. CloudFormation templates must be submitted in the form of a public URL.
+ Use the AWS Marketplace Management Portal to submit your listing. From **Assets**, choose **File upload**, attach your file, and then choose **Upload**. After we receive your template and metadata, AWS starts processing your request.

After you submit your listing, AWS Marketplace reviews and validates the product load form. Additionally, AWS Marketplace regionalizes AMIs and serverless applications, and updates the regional mapping for your CloudFormation template on your behalf. If any issues occur, the AWS Marketplace Seller Operations team will contact you by email. 