export const meta = {
  title: `Use CloudFormation to add custom AWS resources`,
  description: 'The Amplify CLI provides the ability to add custom AWS resources with AWS CloudFormation. Running the `amplify add custom` command in your Amplify project provides CloudFormation starter templates along with mechanisms to reference other Amplify-generated resources.',
};

The Amplify CLI provides the ability to add custom AWS resources with AWS CloudFormation. Running the `amplify add custom` command in your Amplify project provides CloudFormation starter templates along with mechanisms to reference other Amplify-generated resources.

To add custom AWS resources using AWS CloudFormation, run the following command:

```bash
amplify add custom
```
```console
? How do you want to define this custom resource? …  (Use arrow keys or type to filter)
  AWS CDK
❯ AWS CloudFormation
```

A skeleton CloudFormation template is generated in the `amplify/backend/custom/<resource-name>` directory. The additional AWS resources can be defined in the `<resource-name>-cloudformation-template.json` CloudFormation template file.

```json
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "env": {
      "Type": "String"
    }
  },
  "Resources": {
    "snstopic1234": {
      "Type": "AWS::SNS::Topic",
      "Properties": {
        "TopicName": {
          "Fn::Join": [ "", [ "sns-topic-1234-", { "Ref": "env" } ] ]
        }
      }
    },
    "snstopicemailsub1234": {
      "Type": "AWS::SNS::Subscription",
      "Properties": {
        "Protocol": "email",
        "TopicArn": {
          "Ref": "snstopic1234"
        },
        "Endpoint": "<your-email-address>"
      }
    }
  },
  "Outputs": {}
}
```

> Note: Always append the Amplify environment name (`env` parameter) to a resource name to ensure correct behavior with Amplify's multi-environment workflows.

## Reference Amplify backend name

Amplify CLI will automatically populate the `env` parameter in the top of your CloudFormation template. 

```json
...
  "Parameters": {
    "env": {
      "Type": "String"
    }
  },
...
```

To reference the parameter use the [`Ref`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) intrinsic function:

```json
...
  "Resources": {
    "snstopic1234": {
      "Type": "AWS::SNS::Topic",
      "Properties": {
        "TopicName": {
          "Fn::Join": [ "", [ "sns-topic-1234-", { "Ref": "env" } ] ]
        }
      }
    }
  }
...
```

## Reference Amplify-generated resources

The CloudFormation template for custom AWS resources can reference Amplify-generated resources' CloudFormation outputs. To reference another resource's output, run:

```bash
amplify update custom
```
```console
✔ Do you want to access Amplify generated resources in your custom CloudFormation file? (y/N) · yes
? Select the categories you want this custom resource to have access to:
❯ <category>
? Function has 2 resources in this project. Select the one you would like your custom resource to access
❯ ...
```

Once the resources are selected, you can reference the resources' output listed as parameters on the top of your CloudFormation template. To reference the parameter use the [`Ref`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) intrinsic function:

```json
...
  "Parameters": {
    ...,
    "myFunctionArn": {
      "Type": "String"
    }
  },
  "Resources": {
    ...: {
      "Type": ...,
      "Properties": {
        ...: { "Ref": "myFunctionArn"}
      }
    }
  }
...
```