AWS SAMでデプロイ済みのAPI Gatewayの不要な「Stage」を削除する with OpenAPI

デプロイ済みのAPIから、不要な「Stage」を削除します。OpenAPIを利用するAPIの場合です。
2023.01.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS SAMを使ってAPI Gatewayをデプロイしたとき、不要なStageが作成されていました。デプロイ済みのAPIから削除してみました。

なお、本記事では、「OpenAPIを利用してデプロイしたAPI」を扱います。

おすすめの方

  • AWS SAMでOpenAPIを利用するAPI(デプロイ済み)から不要な「Stage」を削除したい方

準備:APIをデプロイする(複数のステージがある)

sam init

sam init \
    --runtime python3.9 \
    --name ApiGateway-Stage-with-OpenAPI-Sample \
    --app-template hello-world \
    --no-tracing \
    --package-type Zip

AWS SAMテンプレート

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ApiGateway-Stage-with-OpenAPI-Sample

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: dev
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: s3://cm-fujii.genki-deploy/ApiGateway-Stage-with-OpenAPI-Sample-Stack/api.yaml

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Timeout: 5
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !Ref MyApi

  HelloWorldFunctionLogGroup:
      Type: AWS::Logs::LogGroup
      Properties:
        LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}

OpenAPI

api.yaml

openapi: 3.0.1
info:
  title: sample api
  version: 1.0.0

paths:
  /hello:
    get:
      tags:
        - hello
      responses:
        200:
          $ref: "#/components/responses/200"
        401:
          $ref: "#/components/responses/401"
        403:
          $ref: "#/components/responses/403"
        500:
          $ref: "#/components/responses/500"
      x-amazon-apigateway-integration:
        type: aws_proxy
        uri:
          'Fn::Sub': >-
            arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorldFunction.Arn}/invocations
        httpMethod: POST
        responses:
          default:
            statusCode: 200
        passthroughBehavior: when_no_templates
        contentHandling: CONVERT_TO_TEXT

components:
  responses:
    200:
      description: Success
    401:
      description: Unauthorized
    403:
      description: User or client is not authorized.
    500:
      description: Internal Server Error

Lambdaコード

app.py

import json

def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
        }),
    }

デプロイ

aws s3 cp \
    api.yaml \
    s3://cm-fujii.genki-deploy/ApiGateway-Stage-with-OpenAPI-Sample-Stack/api.yaml

sam package \
    --output-template-file packaged.yaml \
    --s3-bucket cm-fujii.genki-deploy

sam deploy \
    --template-file packaged.yaml \
    --stack-name ApiGateway-Stage-with-OpenAPI-Sample-Stack \
    --s3-bucket cm-fujii.genki-deploy \
    --capabilities CAPABILITY_NAMED_IAM \
    --no-fail-on-empty-changeset

API Gatewayのステージは、2つできた

「dev」と「Stage」の2つのステージができました。

不要なStageがデプロイされている

API Gateway用の設定にOpenApiVersionを追加する

既存のAPI定義にOpenApiVersionを追加しました。なお、Globalsに追加しても大丈夫です。

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ApiGateway-Stage-with-OpenAPI-Sample

# Globalsへの追加でもOK
# Globals:
#   Api:
#     OpenApiVersion: 3.0.1

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: dev
      OpenApiVersion: 3.0.1
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: s3://cm-fujii.genki-deploy/ApiGateway-Stage-with-OpenAPI-Sample-Stack/api.yaml

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Timeout: 5
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !Ref MyApi

  HelloWorldFunctionLogGroup:
      Type: AWS::Logs::LogGroup
      Properties:
        LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}

デプロイ前に、Stageを手動で削除する

マネジメントコンソールなどで、Stageを削除します。

不要なStageを削除する

Stageが無くなり、増えていない

デプロイする

さきほどのコマンドでデプロイします。成功します。

API Gatewayのステージは1つのまま(増えてない)

API Gatewayのステージは、1つのままです。増えていません。

Stageが無くなり、増えていない

さいごに

OpenAPIを利用した場合の対処方法をご紹介しました。 参考になれば幸いです。

参考