Repository: aws/serverless-application-model

Issue:
Feature Request: AWS SAM does not support Description property for AWS::Serverless::Api
**Description:**
This is not a bug or an issue. It is more like a feature request.

I noticed while creating an API today that AWS SAM does not support a `Description` property for `AWS::Serverless::Api` resource.

Can this property be added to AWS SAM? We have many APIs created and currently, it's not easy to tell their usage. So, being able to set the `Description` property would be a very nice ability to have.

**Expected result:**

`AWS::Serverless::Api` has a `Description` property where we set a custom description:

```
MyApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: "MyApi"
      StageName: "v1"
      Description: "This is my API"
```

Thank you




Discussion:
If somebody could point me the right direction about where to start, I'd be happy to try adding support for this myself and then submit a pull request. 

I tried to look in the repo but could find a starting point(some type of function/class or file where I should start)
Is there a reason why it was not added from the start ?  CFN supports it... and it looks straightforward enough to add, what issue are we running into ?
Hi there,

Are there any updates on this feature request?

Thank you in advance!
It needs to be added here and probably some test cases:
-  https://github.com/aws/serverless-application-model/blob/02ec8bf95e33d8e5da536a75ad16cb9c6ff69d09/samtranslator/validator/sam_schema/schema.json 
- https://github.com/aws/serverless-application-model/blob/97dbedfeb2551633f32b02b14e271cc84fd3c5a1/samtranslator/model/sam_resources.py


Resolving patch:
diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py
--- a/samtranslator/model/api/api_generator.py
+++ b/samtranslator/model/api/api_generator.py
@@ -85,6 +85,7 @@ def __init__(
         open_api_version=None,
         models=None,
         domain=None,
+        description=None,
     ):
         """Constructs an API Generator class that generates API Gateway resources
 
@@ -104,6 +105,7 @@ def __init__(
         :param resource_attributes: Resource attributes to add to API resources
         :param passthrough_resource_attributes: Attributes such as `Condition` that are added to derived resources
         :param models: Model definitions to be used by API methods
+        :param description: Description of the API Gateway resource
         """
         self.logical_id = logical_id
         self.cache_cluster_enabled = cache_cluster_enabled
@@ -131,6 +133,7 @@ def __init__(
         self.remove_extra_stage = open_api_version
         self.models = models
         self.domain = domain
+        self.description = description
 
     def _construct_rest_api(self):
         """Constructs and returns the ApiGateway RestApi.
@@ -181,6 +184,9 @@ def _construct_rest_api(self):
         if self.name:
             rest_api.Name = self.name
 
+        if self.description:
+            rest_api.Description = self.description
+
         return rest_api
 
     def _construct_body_s3_dict(self):
diff --git a/samtranslator/model/api/http_api_generator.py b/samtranslator/model/api/http_api_generator.py
--- a/samtranslator/model/api/http_api_generator.py
+++ b/samtranslator/model/api/http_api_generator.py
@@ -48,6 +48,7 @@ def __init__(
         passthrough_resource_attributes=None,
         domain=None,
         fail_on_warnings=False,
+        description=None,
         disable_execute_api_endpoint=False,
     ):
         """Constructs an API Generator class that generates API Gateway resources
@@ -63,6 +64,7 @@ def __init__(
         :param access_log_settings: Whether to send access logs and where for Stage
         :param resource_attributes: Resource attributes to add to API resources
         :param passthrough_resource_attributes: Attributes such as `Condition` that are added to derived resources
+        :param description: Description of the API Gateway resource
         """
         self.logical_id = logical_id
         self.stage_variables = stage_variables
@@ -82,6 +84,7 @@ def __init__(
         self.passthrough_resource_attributes = passthrough_resource_attributes
         self.domain = domain
         self.fail_on_warnings = fail_on_warnings
+        self.description = description
         self.disable_execute_api_endpoint = disable_execute_api_endpoint
 
     def _construct_http_api(self):
@@ -121,6 +124,9 @@ def _construct_http_api(self):
                 "add a 'HttpApi' event to an 'AWS::Serverless::Function'.",
             )
 
+        if self.description:
+            http_api.Description = self.description
+
         return http_api
 
     def _add_cors(self):
diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py
--- a/samtranslator/model/sam_resources.py
+++ b/samtranslator/model/sam_resources.py
@@ -734,6 +734,7 @@ class SamApi(SamResourceMacro):
         "OpenApiVersion": PropertyType(False, is_str()),
         "Models": PropertyType(False, is_type(dict)),
         "Domain": PropertyType(False, is_type(dict)),
+        "Description": PropertyType(False, is_str()),
     }
 
     referable_properties = {
@@ -787,6 +788,7 @@ def to_cloudformation(self, **kwargs):
             open_api_version=self.OpenApiVersion,
             models=self.Models,
             domain=self.Domain,
+            description=self.Description,
         )
 
         (
@@ -837,6 +839,7 @@ class SamHttpApi(SamResourceMacro):
         "RouteSettings": PropertyType(False, is_type(dict)),
         "Domain": PropertyType(False, is_type(dict)),
         "FailOnWarnings": PropertyType(False, is_type(bool)),
+        "Description": PropertyType(False, is_str()),
         "DisableExecuteApiEndpoint": PropertyType(False, is_type(bool)),
     }
 
@@ -877,6 +880,7 @@ def to_cloudformation(self, **kwargs):
             passthrough_resource_attributes=self.get_passthrough_resource_attributes(),
             domain=self.Domain,
             fail_on_warnings=self.FailOnWarnings,
+            description=self.Description,
             disable_execute_api_endpoint=self.DisableExecuteApiEndpoint,
         )
 


Test patch:
diff --git a/tests/model/test_sam_resources.py b/tests/model/test_sam_resources.py
--- a/tests/model/test_sam_resources.py
+++ b/tests/model/test_sam_resources.py
@@ -4,13 +4,13 @@
 
 from samtranslator.intrinsics.resolver import IntrinsicsResolver
 from samtranslator.model import InvalidResourceException
+from samtranslator.model.apigatewayv2 import ApiGatewayV2HttpApi
 from samtranslator.model.lambda_ import LambdaFunction, LambdaVersion
 from samtranslator.model.apigateway import ApiGatewayRestApi
 from samtranslator.model.apigateway import ApiGatewayDeployment
 from samtranslator.model.apigateway import ApiGatewayStage
 from samtranslator.model.iam import IAMRole
-from samtranslator.model.sam_resources import SamFunction
-from samtranslator.model.sam_resources import SamApi
+from samtranslator.model.sam_resources import SamFunction, SamApi, SamHttpApi
 
 
 class TestCodeUri(TestCase):
@@ -188,3 +188,55 @@ def test_with_tags(self):
 
         self.assertEqual(deployment.__len__(), 1)
         self.assertEqual(deployment[0].Tags, [{"Key": "MyKey", "Value": "MyValue"}])
+
+
+class TestApiDescription(TestCase):
+    kwargs = {
+        "intrinsics_resolver": IntrinsicsResolver({}),
+        "event_resources": [],
+        "managed_policy_map": {"foo": "bar"},
+    }
+
+    @patch("boto3.session.Session.region_name", "eu-central-1")
+    def test_with_no_description(self):
+        sam_api = SamApi("foo")
+
+        resources = sam_api.to_cloudformation(**self.kwargs)
+        rest_api = [x for x in resources if isinstance(x, ApiGatewayRestApi)]
+        self.assertEqual(rest_api[0].Description, None)
+
+    @patch("boto3.session.Session.region_name", "eu-central-1")
+    def test_with_description(self):
+        sam_api = SamApi("foo")
+        sam_api.Description = "my description"
+
+        resources = sam_api.to_cloudformation(**self.kwargs)
+        rest_api = [x for x in resources if isinstance(x, ApiGatewayRestApi)]
+        self.assertEqual(rest_api[0].Description, "my description")
+
+
+class TestHttpApiDescription(TestCase):
+    kwargs = {
+        "intrinsics_resolver": IntrinsicsResolver({}),
+        "event_resources": [],
+        "managed_policy_map": {"foo": "bar"},
+    }
+
+    @patch("boto3.session.Session.region_name", "eu-central-1")
+    def test_with_no_description(self):
+        sam_http_api = SamHttpApi("foo")
+        sam_http_api.DefinitionUri = "s3://foobar/foo.zip"
+
+        resources = sam_http_api.to_cloudformation(**self.kwargs)
+        rest_api = [x for x in resources if isinstance(x, ApiGatewayV2HttpApi)]
+        self.assertEqual(rest_api[0].Description, None)
+
+    @patch("boto3.session.Session.region_name", "eu-central-1")
+    def test_with_description(self):
+        sam_http_api = SamHttpApi("foo")
+        sam_http_api.DefinitionUri = "s3://foobar/foo.zip"
+        sam_http_api.Description = "my description"
+
+        resources = sam_http_api.to_cloudformation(**self.kwargs)
+        rest_api = [x for x in resources if isinstance(x, ApiGatewayV2HttpApi)]
+        self.assertEqual(rest_api[0].Description, "my description")
diff --git a/tests/translator/input/api_description.yaml b/tests/translator/input/api_description.yaml
new file mode 100644
--- /dev/null
+++ b/tests/translator/input/api_description.yaml
@@ -0,0 +1,21 @@
+Resources:
+  Function:
+    Type: AWS::Serverless::Function
+    Properties:
+      CodeUri: s3://sam-demo-bucket/member_portal.zip
+      Handler: index.gethtml
+      Runtime: nodejs12.x
+      Events:
+        GetHtml:
+          Type: Api
+          Properties:
+            RestApiId: Api
+            Path: /
+            Method: get
+
+  Api:
+    Type: AWS::Serverless::Api
+    Properties:
+      StageName: Prod
+      DefinitionUri: s3://sam-demo-bucket/webpage_swagger.json
+      Description: my description
diff --git a/tests/translator/input/http_api_description.yaml b/tests/translator/input/http_api_description.yaml
new file mode 100644
--- /dev/null
+++ b/tests/translator/input/http_api_description.yaml
@@ -0,0 +1,18 @@
+Resources:
+  HttpApi:
+    Type: AWS::Serverless::HttpApi
+    Properties:
+      DefinitionUri: s3://bucket/key
+      Description: my description
+
+  Function:
+    Type: AWS::Serverless::Function
+    Properties:
+      Runtime: python3.7
+      Handler: index.handler
+      CodeUri: s3://bucket/key
+      Events:
+        Api:
+          Type: HttpApi
+          Properties:
+            ApiId: HttpApi
diff --git a/tests/translator/output/api_description.json b/tests/translator/output/api_description.json
new file mode 100644
--- /dev/null
+++ b/tests/translator/output/api_description.json
@@ -0,0 +1,108 @@
+{
+  "Resources": {
+    "FunctionRole": {
+      "Type": "AWS::IAM::Role", 
+      "Properties": {
+        "ManagedPolicyArns": [
+          "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+        ],
+        "Tags": [
+          {
+            "Value": "SAM",
+            "Key": "lambda:createdBy"
+          }
+        ],
+        "AssumeRolePolicyDocument": {
+          "Version": "2012-10-17", 
+          "Statement": [
+            {
+              "Action": [
+                "sts:AssumeRole"
+              ], 
+              "Effect": "Allow", 
+              "Principal": {
+                "Service": [
+                  "lambda.amazonaws.com"
+                ]
+              }
+            }
+          ]
+        }
+      }
+    }, 
+    "ApiProdStage": {
+      "Type": "AWS::ApiGateway::Stage", 
+      "Properties": {
+        "DeploymentId": {
+          "Ref": "ApiDeploymentf117c932f7"
+        }, 
+        "RestApiId": {
+          "Ref": "Api"
+        }, 
+        "StageName": "Prod"
+      }
+    }, 
+    "FunctionGetHtmlPermissionProd": {
+      "Type": "AWS::Lambda::Permission", 
+      "Properties": {
+        "Action": "lambda:InvokeFunction", 
+        "Principal": "apigateway.amazonaws.com", 
+        "FunctionName": {
+          "Ref": "Function"
+        }, 
+        "SourceArn": {
+          "Fn::Sub": [
+            "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", 
+            {
+              "__Stage__": "*",
+              "__ApiId__": "Api"
+            }
+          ]
+        }
+      }
+    },
+    "ApiDeploymentf117c932f7": {
+      "Type": "AWS::ApiGateway::Deployment", 
+      "Properties": {
+        "RestApiId": {
+          "Ref": "Api"
+        }, 
+        "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", 
+        "StageName": "Stage"
+      }
+    }, 
+    "Api": {
+      "Type": "AWS::ApiGateway::RestApi", 
+      "Properties": {
+        "BodyS3Location": {
+          "Bucket": "sam-demo-bucket", 
+          "Key": "webpage_swagger.json"
+        },
+        "Description": "my description"
+      }
+    }, 
+    "Function": {
+      "Type": "AWS::Lambda::Function", 
+      "Properties": {
+        "Code": {
+          "S3Bucket": "sam-demo-bucket", 
+          "S3Key": "member_portal.zip"
+        }, 
+        "Handler": "index.gethtml", 
+        "Role": {
+          "Fn::GetAtt": [
+            "FunctionRole",
+            "Arn"
+          ]
+        }, 
+        "Runtime": "nodejs12.x",
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }
+  }
+}
diff --git a/tests/translator/output/aws-cn/api_description.json b/tests/translator/output/aws-cn/api_description.json
new file mode 100644
--- /dev/null
+++ b/tests/translator/output/aws-cn/api_description.json
@@ -0,0 +1,116 @@
+{
+  "Resources": {
+    "FunctionRole": {
+      "Type": "AWS::IAM::Role", 
+      "Properties": {
+        "ManagedPolicyArns": [
+          "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+        ],
+        "Tags": [
+          {
+            "Value": "SAM",
+            "Key": "lambda:createdBy"
+          }
+        ],
+        "AssumeRolePolicyDocument": {
+          "Version": "2012-10-17", 
+          "Statement": [
+            {
+              "Action": [
+                "sts:AssumeRole"
+              ], 
+              "Effect": "Allow", 
+              "Principal": {
+                "Service": [
+                  "lambda.amazonaws.com"
+                ]
+              }
+            }
+          ]
+        }
+      }
+    }, 
+    "ApiProdStage": {
+      "Type": "AWS::ApiGateway::Stage", 
+      "Properties": {
+        "DeploymentId": {
+          "Ref": "ApiDeploymentf117c932f7"
+        }, 
+        "RestApiId": {
+          "Ref": "Api"
+        }, 
+        "StageName": "Prod"
+      }
+    }, 
+    "FunctionGetHtmlPermissionProd": {
+      "Type": "AWS::Lambda::Permission", 
+      "Properties": {
+        "Action": "lambda:InvokeFunction", 
+        "Principal": "apigateway.amazonaws.com", 
+        "FunctionName": {
+          "Ref": "Function"
+        }, 
+        "SourceArn": {
+          "Fn::Sub": [
+            "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/",
+            {
+              "__Stage__": "*",
+              "__ApiId__": "Api"
+            }
+          ]
+        }
+      }
+    },
+    "ApiDeploymentf117c932f7": {
+      "Type": "AWS::ApiGateway::Deployment", 
+      "Properties": {
+        "RestApiId": {
+          "Ref": "Api"
+        }, 
+        "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", 
+        "StageName": "Stage"
+      }
+    }, 
+    "Api": {
+      "Type": "AWS::ApiGateway::RestApi", 
+      "Properties": {
+        "BodyS3Location": {
+          "Bucket": "sam-demo-bucket", 
+          "Key": "webpage_swagger.json"
+        },
+        "Description": "my description",
+        "EndpointConfiguration": {
+          "Types": [
+            "REGIONAL"
+          ]
+        },
+        "Parameters": {
+          "endpointConfigurationTypes": "REGIONAL"
+        }
+      }
+    }, 
+    "Function": {
+      "Type": "AWS::Lambda::Function", 
+      "Properties": {
+        "Code": {
+          "S3Bucket": "sam-demo-bucket", 
+          "S3Key": "member_portal.zip"
+        }, 
+        "Handler": "index.gethtml", 
+        "Role": {
+          "Fn::GetAtt": [
+            "FunctionRole",
+            "Arn"
+          ]
+        }, 
+        "Runtime": "nodejs12.x",
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }
+  }
+}
diff --git a/tests/translator/output/aws-cn/http_api_description.json b/tests/translator/output/aws-cn/http_api_description.json
new file mode 100644
--- /dev/null
+++ b/tests/translator/output/aws-cn/http_api_description.json
@@ -0,0 +1,96 @@
+{
+  "Resources": {
+    "Function": {
+      "Type": "AWS::Lambda::Function", 
+      "Properties": {
+        "Handler": "index.handler", 
+        "Code": {
+          "S3Bucket": "bucket", 
+          "S3Key": "key"
+        }, 
+        "Role": {
+          "Fn::GetAtt": [
+            "FunctionRole", 
+            "Arn"
+          ]
+        }, 
+        "Runtime": "python3.7", 
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }, 
+    "FunctionApiPermission": {
+      "Type": "AWS::Lambda::Permission", 
+      "Properties": {
+        "Action": "lambda:InvokeFunction", 
+        "Principal": "apigateway.amazonaws.com", 
+        "FunctionName": {
+          "Ref": "Function"
+        }, 
+        "SourceArn": {
+          "Fn::Sub": [
+            "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", 
+            {
+              "__Stage__": "*", 
+              "__ApiId__": "HttpApi"
+            }
+          ]
+        }
+      }
+    },
+    "FunctionRole": {
+      "Type": "AWS::IAM::Role", 
+      "Properties": {
+        "AssumeRolePolicyDocument": {
+          "Version": "2012-10-17", 
+          "Statement": [
+            {
+              "Action": [
+                "sts:AssumeRole"
+              ], 
+              "Effect": "Allow", 
+              "Principal": {
+                "Service": [
+                  "lambda.amazonaws.com"
+                ]
+              }
+            }
+          ]
+        }, 
+        "ManagedPolicyArns": [
+          "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+        ], 
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }, 
+    "HttpApiApiGatewayDefaultStage": {
+      "Type": "AWS::ApiGatewayV2::Stage", 
+      "Properties": {
+        "AutoDeploy": true, 
+        "ApiId": {
+          "Ref": "HttpApi"
+        },
+        "StageName": "$default"
+      }
+    }, 
+    "HttpApi": {
+      "Type": "AWS::ApiGatewayV2::Api", 
+      "Properties": {
+        "BodyS3Location": {
+          "Bucket": "bucket",
+          "Key": "key"
+        },
+        "Description": "my description"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tests/translator/output/aws-us-gov/api_description.json b/tests/translator/output/aws-us-gov/api_description.json
new file mode 100644
--- /dev/null
+++ b/tests/translator/output/aws-us-gov/api_description.json
@@ -0,0 +1,116 @@
+{
+  "Resources": {
+    "FunctionRole": {
+      "Type": "AWS::IAM::Role", 
+      "Properties": {
+        "ManagedPolicyArns": [
+          "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+        ],
+        "Tags": [
+          {
+            "Value": "SAM",
+            "Key": "lambda:createdBy"
+          }
+        ],
+        "AssumeRolePolicyDocument": {
+          "Version": "2012-10-17", 
+          "Statement": [
+            {
+              "Action": [
+                "sts:AssumeRole"
+              ], 
+              "Effect": "Allow", 
+              "Principal": {
+                "Service": [
+                  "lambda.amazonaws.com"
+                ]
+              }
+            }
+          ]
+        }
+      }
+    }, 
+    "ApiProdStage": {
+      "Type": "AWS::ApiGateway::Stage", 
+      "Properties": {
+        "DeploymentId": {
+          "Ref": "ApiDeploymentf117c932f7"
+        }, 
+        "RestApiId": {
+          "Ref": "Api"
+        }, 
+        "StageName": "Prod"
+      }
+    }, 
+    "FunctionGetHtmlPermissionProd": {
+      "Type": "AWS::Lambda::Permission", 
+      "Properties": {
+        "Action": "lambda:InvokeFunction", 
+        "Principal": "apigateway.amazonaws.com", 
+        "FunctionName": {
+          "Ref": "Function"
+        }, 
+        "SourceArn": {
+          "Fn::Sub": [
+            "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/",
+            {
+              "__Stage__": "*",
+              "__ApiId__": "Api"
+            }
+          ]
+        }
+      }
+    },
+    "ApiDeploymentf117c932f7": {
+      "Type": "AWS::ApiGateway::Deployment", 
+      "Properties": {
+        "RestApiId": {
+          "Ref": "Api"
+        }, 
+        "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", 
+        "StageName": "Stage"
+      }
+    }, 
+    "Api": {
+      "Type": "AWS::ApiGateway::RestApi", 
+      "Properties": {
+        "BodyS3Location": {
+          "Bucket": "sam-demo-bucket", 
+          "Key": "webpage_swagger.json"
+        },
+        "Description": "my description",
+        "EndpointConfiguration": {
+          "Types": [
+            "REGIONAL"
+          ]
+        },
+        "Parameters": {
+          "endpointConfigurationTypes": "REGIONAL"
+        }
+      }
+    }, 
+    "Function": {
+      "Type": "AWS::Lambda::Function", 
+      "Properties": {
+        "Code": {
+          "S3Bucket": "sam-demo-bucket", 
+          "S3Key": "member_portal.zip"
+        }, 
+        "Handler": "index.gethtml", 
+        "Role": {
+          "Fn::GetAtt": [
+            "FunctionRole",
+            "Arn"
+          ]
+        }, 
+        "Runtime": "nodejs12.x",
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }
+  }
+}
diff --git a/tests/translator/output/aws-us-gov/http_api_description.json b/tests/translator/output/aws-us-gov/http_api_description.json
new file mode 100644
--- /dev/null
+++ b/tests/translator/output/aws-us-gov/http_api_description.json
@@ -0,0 +1,96 @@
+{
+  "Resources": {
+    "Function": {
+      "Type": "AWS::Lambda::Function", 
+      "Properties": {
+        "Handler": "index.handler", 
+        "Code": {
+          "S3Bucket": "bucket", 
+          "S3Key": "key"
+        }, 
+        "Role": {
+          "Fn::GetAtt": [
+            "FunctionRole", 
+            "Arn"
+          ]
+        }, 
+        "Runtime": "python3.7", 
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }, 
+    "FunctionApiPermission": {
+      "Type": "AWS::Lambda::Permission", 
+      "Properties": {
+        "Action": "lambda:InvokeFunction", 
+        "Principal": "apigateway.amazonaws.com", 
+        "FunctionName": {
+          "Ref": "Function"
+        }, 
+        "SourceArn": {
+          "Fn::Sub": [
+            "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", 
+            {
+              "__Stage__": "*", 
+              "__ApiId__": "HttpApi"
+            }
+          ]
+        }
+      }
+    },
+    "FunctionRole": {
+      "Type": "AWS::IAM::Role", 
+      "Properties": {
+        "AssumeRolePolicyDocument": {
+          "Version": "2012-10-17", 
+          "Statement": [
+            {
+              "Action": [
+                "sts:AssumeRole"
+              ], 
+              "Effect": "Allow", 
+              "Principal": {
+                "Service": [
+                  "lambda.amazonaws.com"
+                ]
+              }
+            }
+          ]
+        }, 
+        "ManagedPolicyArns": [
+          "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+        ], 
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }, 
+    "HttpApiApiGatewayDefaultStage": {
+      "Type": "AWS::ApiGatewayV2::Stage", 
+      "Properties": {
+        "AutoDeploy": true, 
+        "ApiId": {
+          "Ref": "HttpApi"
+        },
+        "StageName": "$default"
+      }
+    }, 
+    "HttpApi": {
+      "Type": "AWS::ApiGatewayV2::Api", 
+      "Properties": {
+        "BodyS3Location": {
+          "Bucket": "bucket",
+          "Key": "key"
+        },
+        "Description": "my description"
+      }
+    }
+  }
+}
diff --git a/tests/translator/output/http_api_description.json b/tests/translator/output/http_api_description.json
new file mode 100644
--- /dev/null
+++ b/tests/translator/output/http_api_description.json
@@ -0,0 +1,96 @@
+{
+  "Resources": {
+    "Function": {
+      "Type": "AWS::Lambda::Function", 
+      "Properties": {
+        "Handler": "index.handler", 
+        "Code": {
+          "S3Bucket": "bucket", 
+          "S3Key": "key"
+        }, 
+        "Role": {
+          "Fn::GetAtt": [
+            "FunctionRole", 
+            "Arn"
+          ]
+        }, 
+        "Runtime": "python3.7", 
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }, 
+    "FunctionApiPermission": {
+      "Type": "AWS::Lambda::Permission", 
+      "Properties": {
+        "Action": "lambda:InvokeFunction", 
+        "Principal": "apigateway.amazonaws.com", 
+        "FunctionName": {
+          "Ref": "Function"
+        }, 
+        "SourceArn": {
+          "Fn::Sub": [
+            "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", 
+            {
+              "__Stage__": "*", 
+              "__ApiId__": "HttpApi"
+            }
+          ]
+        }
+      }
+    },
+    "FunctionRole": {
+      "Type": "AWS::IAM::Role", 
+      "Properties": {
+        "AssumeRolePolicyDocument": {
+          "Version": "2012-10-17", 
+          "Statement": [
+            {
+              "Action": [
+                "sts:AssumeRole"
+              ], 
+              "Effect": "Allow", 
+              "Principal": {
+                "Service": [
+                  "lambda.amazonaws.com"
+                ]
+              }
+            }
+          ]
+        }, 
+        "ManagedPolicyArns": [
+          "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+        ], 
+        "Tags": [
+          {
+            "Value": "SAM", 
+            "Key": "lambda:createdBy"
+          }
+        ]
+      }
+    }, 
+    "HttpApiApiGatewayDefaultStage": {
+      "Type": "AWS::ApiGatewayV2::Stage", 
+      "Properties": {
+        "AutoDeploy": true, 
+        "ApiId": {
+          "Ref": "HttpApi"
+        },
+        "StageName": "$default"
+      }
+    }, 
+    "HttpApi": {
+      "Type": "AWS::ApiGatewayV2::Api", 
+      "Properties": {
+        "BodyS3Location": {
+          "Bucket": "bucket",
+          "Key": "key"
+        },
+        "Description": "my description"
+      }
+    }
+  }
+}
diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py
--- a/tests/translator/test_translator.py
+++ b/tests/translator/test_translator.py
@@ -161,6 +161,7 @@ class TestTranslatorEndToEnd(TestCase):
                 "simpletable_with_sse",
                 "implicit_api",
                 "explicit_api",
+                "api_description",
                 "api_endpoint_configuration",
                 "api_endpoint_configuration_with_vpcendpoint",
                 "api_with_auth_all_maximum",
@@ -380,6 +381,7 @@ def test_transform_success(self, testcase, partition_with_region):
                 "http_api_def_uri",
                 "explicit_http_api",
                 "http_api_with_cors",
+                "http_api_description",
                 "http_api_lambda_auth",
                 "http_api_lambda_auth_full",
             ],