42

I'm creating AWS Cloudformation template for my environment and I can't find a way to enable CORS for API Gateway method.

I can configure it using AWS console (here is the official doc), but how can I do it in the Cloudformation template?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
dds
  • 2,335
  • 1
  • 31
  • 45

5 Answers5

77

After some trial and error, I found that the following CloudFormation template snippet will produce an equivalent OPTIONS method when compared to the CORS console wizard:

OptionsMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    AuthorizationType: NONE
    RestApiId:
      Ref: MyApi
    ResourceId:
      Ref: MyResourceOnWhichToEnableCORS
    HttpMethod: OPTIONS
    Integration:
      IntegrationResponses:
      - StatusCode: 200
        ResponseParameters:
          method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
          method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'"
          method.response.header.Access-Control-Allow-Origin: "'*'"
        ResponseTemplates:
          application/json: ''
      PassthroughBehavior: WHEN_NO_MATCH
      RequestTemplates:
        application/json: '{"statusCode": 200}'
      Type: MOCK
    MethodResponses:
    - StatusCode: 200
      ResponseModels:
        application/json: 'Empty'
      ResponseParameters:
          method.response.header.Access-Control-Allow-Headers: false
          method.response.header.Access-Control-Allow-Methods: false
          method.response.header.Access-Control-Allow-Origin: false

*Note 1: This is an example of taking the defaults for a POST. Obviously, you'll need to update Access-Control-Allow-Methods to include the values you need.

*Note 2: Kudos to the AWS CloudFormation team for recently introducing YAML support. If you need to convert to/from YAML/JSON, I have found this site handy: http://www.json2yaml.com/

Yves M.
  • 29,855
  • 23
  • 108
  • 144
dannymac
  • 1,641
  • 13
  • 8
  • 4
    shouldn't the booleans at the end all be `true` instead of `false`? – Dave Moten Nov 25 '17 at 08:19
  • 1
    @DaveMoten Unlikely. From the docs: "The Boolean specifies whether a parameter is required." https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apitgateway-method-methodresponse.html#cfn-apigateway-method-methodresponse-responseparameters – Leandros Jun 07 '19 at 12:11
  • hi @dannymac, can you help me with this CORS error? https://stackoverflow.com/questions/56688796/cloudformation-api-gateway-cors-issue – Viet Jun 24 '19 at 20:27
  • I have a similar issue, I tried this but didn't work for me - https://stackoverflow.com/questions/57655298/aws-how-to-enable-cors-in-api-gateway-using-cloudformation – Dev1ce Aug 26 '19 at 09:45
  • What is 'Ref: MyApi'? Please show the other relevant resources - MyApi and MyResourceOnWhichToEnableCORS – Rony Tesler Jan 02 '21 at 23:44
  • And also the 'Empty' model if possible. – Rony Tesler Jan 02 '21 at 23:52
3

The API Gateway support for automatic CORS configuration currently only works via the API Gateway console. You can still set-up CORS yourself when importing an API from swagger or when defining an API via CloudFormation, but you must specify all the parameters for setting up the OPTIONS method as well as adding the CORS specific headers to your other methods.

This page shows how to set-up CORS when importing swagger. Setting up CORS via CloudFormation is conceptually similar, but uses the CloudFormation syntax rather than the swagger syntax.

MikeD at AWS
  • 3,565
  • 16
  • 15
3

Try this:

  OPTIONS: 
   Type: AWS::ApiGateway::Method 
   Properties: ApiKeyRequired: false
   RestApiId: !Ref YourAPI 
   ResourceId: !Ref YourResourceName 
   HttpMethod: OPTIONS 
   AuthorizationType: NONE 
   Integration: 
    Type: MOCK 
    IntegrationResponses: 
     - StatusCode: 200 
     ResponseParameters: 
      method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'" 
      method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'" 
      method.response.header.Access-Control-Allow-Origin: "'*'" 
     ResponseTemplates: 
      application/json: '' 
    PassthroughBehavior: WHEN_NO_MATCH 
    RequestTemplates: 
     application/json: '{"statusCode": 200}' 
    Type: MOCK 
   MethodResponses: 
   - StatusCode: 200 
   ResponseModels: 
    application/json: 'Empty' 
   ResponseParameters: 
    method.response.header.Access-Control-Allow-Headers: false 
    method.response.header.Access-Control-Allow-Methods: false 
    method.response.header.Access-Control-Allow-Origin: false
Anoop
  • 385
  • 2
  • 10
2

it only create option method, there are still work need to do on GET,POST,etc method reponse, I have created a completed hello world cloudformation

https://github.com/seraphjiang/aws-cors-cloudformation/tree/master

Huan Jiang
  • 247
  • 4
  • 13
2

This snippet has worked for my team's deployments. Note that this is a proxy resource with an ANY method.

CORSOptionsMethod: # Adds cors
    Type: "AWS::ApiGateway::Method"
    Properties:
      ResourceId:
        !Ref apiProxy
      RestApiId:
        !Ref api
      AuthorizationType: NONE
      HttpMethod: OPTIONS
      Integration:
        Type: MOCK
        IntegrationResponses:
          - ResponseParameters:
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'"
              method.response.header.Access-Control-Allow-Methods: "'GET,POST,PUT,DELETE,OPTIONS'"
              method.response.header.Access-Control-Allow-Origin: !Sub
                - "'${CORSOrigin}'"
                - { 'CORSOrigin': !FindInMap [Environment, !Ref Environment, CORSOrigin] }
            ResponseTemplates:
              application/json: ''
            StatusCode: '200'
        PassthroughBehavior: NEVER
        RequestTemplates:
          application/json: '{"statusCode": 200}'
      MethodResponses:
        - ResponseModels:
            application/json: Empty
          ResponseParameters:
            method.response.header.Access-Control-Allow-Headers: true
            method.response.header.Access-Control-Allow-Methods: true
            method.response.header.Access-Control-Allow-Origin: true
          StatusCode: '200'
jones-chris
  • 629
  • 2
  • 13
  • 29