5
votes

I have setup an API Gateway (v1, not v2) REST API resource using CloudFormation template. Recently I have noticed that the default execute-api endpoint is also created, which I can disable in the settings.

enter image description here The type of this API is AWS::ApiGateway::RestApi.

Naturally, I would like this to be done through the template, so the question is: can this setting be defined in the CloudFormation template, rather than havign to be clicked manually in the AWS Console? This option is available for the APIGateway V2 API resource (AWS::ApiGatewayV2::Api) but not the APIGateway V1 REST API resource (AWS::ApiGateway::RestApi) in the CloudFormation templates, even though it can be changed manuall for the APIGateway V1 REST API in the console.

There is also a CLI way of doing this for the AWS::ApiGateway::RestApi.

Here are some links I have used to search for this setting:
AWS::ApiGatewayV2::API
AWS::ApiGateway::RestApi
Disabling default api-execute endpoint via CLI

4
as per the documentation it is not supported in the Cloudformation definition. But there is an option inRestAPI Create Call. If you really would like to do it in the CFN you can leverage Running bash commands in AWS CloudFormation templatessamtoddler

4 Answers

3
votes

Support for disabling the default execute-api endpoint has recently been added to AWS::ApiGateway::RestApi cloudformation: DisableExecuteApiEndpoint

MyRestApi:
  Type: 'AWS::ApiGateway::RestApi'
  Properties:
    DisableExecuteApiEndpoint: true
1
votes

You can disable it though a simple custom resource. Below is an example of such a fully working template that does that:


Resources:

  MyRestApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Description: A test API
      Name: MyRestAPI


  LambdaBasicExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonAPIGatewayAdministrator
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  MyCustomResource:
    Type: Custom::DisableDefaultApiEndpoint
    Properties:
      ServiceToken: !GetAtt 'MyCustomFunction.Arn'
      APIId: !Ref 'MyRestApi'

  MyCustomFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.lambda_handler
      Description: "Disable default API endpoint"
      Timeout: 30
      Role: !GetAtt 'LambdaBasicExecutionRole.Arn'
      Runtime: python3.7
      Code:
        ZipFile: |
          import json
          import logging
          import cfnresponse
          import boto3
          
          logger = logging.getLogger()
          logger.setLevel(logging.INFO)

          client = boto3.client('apigateway')

          def lambda_handler(event, context):
            logger.info('got event {}'.format(event))  
            try:

              responseData = {}

              if event['RequestType'] in ["Create"]:                      
                
                APIId = event['ResourceProperties']['APIId']                
                
                response = client.update_rest_api(
                    restApiId=APIId,
                    patchOperations=[
                        {
                            'op': 'replace',
                            'path': '/disableExecuteApiEndpoint',
                            'value': 'True'
                        }
                    ]
                )

                logger.info(str(response))

                cfnresponse.send(event, context, 
                                 cfnresponse.SUCCESS, responseData)

              else:
                logger.info('Unexpected RequestType!') 
                cfnresponse.send(event, context, 
                                  cfnresponse.SUCCESS, responseData)

            except Exception as err:

              logger.error(err)
              responseData = {"Data": str(err)}
              cfnresponse.send(event,context, 
                               cfnresponse.FAILED,responseData)
            return              

1
votes

In case anyone stumbles across this answer that is using CDK, this can be done concisely (without defining a Lambda function) using the AwsCustomResource construct:

const restApi = new apigw.RestApi(...);
const executeApiResource = new cr.AwsCustomResource(this, "execute-api-resource", {
  functionName: "disable-execute-api-endpoint",
  onCreate: {
    service: "APIGateway",
    action: "updateRestApi",
    parameters: {
      restApiId: restApi.restApiId,
      patchOperations: [{
        op: "replace",
        path: "/disableExecuteApiEndpoint",
        value: "True"
      }]
    },
    physicalResourceId: cr.PhysicalResourceId.of("execute-api-resource")
  },
  policy: cr.AwsCustomResourcePolicy.fromStatements([new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    actions: ["apigateway:PATCH"],
    resources: ["arn:aws:apigateway:*::/*"],
  })])
});
executeApiResource.node.addDependency(restApi);
0
votes

You can disable it in AWS CDK. This is done by finding the CloudFormation resource and setting it to true.

   const api = new apigateway.RestApi(this, 'api', );
   (api.node.children[0] as apigateway.CfnRestApi).addPropertyOverride('DisableExecuteApiEndpoint','true')