I Want to use APIGateway for my RESTful application by OpenApi file but How could I inject my variables from outside of swagger file into it
Swagger.yml
openapi: "3.0.1"
info:
title: !Join ['-', ['XXXX', !Ref ServiceName]]
paths:
/:
get:
responses:
default:
description: "Default response for GET /"
x-amazon-apigateway-integration:
payloadFormatVersion: "1.0"
connectionId: !Ref VPCLink
type: "http_proxy"
httpMethod: "ANY"
uri: !GetAtt ServiceDiscovery.Arn
connectionType: "VPC_LINK"
/health:
get:
responses:
default:
description: "Default response for GET /health"
x-amazon-apigateway-integration:
payloadFormatVersion: "1.0"
connectionId: !Ref VPCLink
type: "http_proxy"
httpMethod: "ANY"
uri: !GetAtt ServiceDiscovery.Arn
connectionType: "VPC_LINK"
x-amazon-apigateway-cors:
allowOrigins:
- '*'
allowHeaders:
- '*'
allowMethods:
- 'GET'
x-amazon-apigateway-importexport-version: "1.0"
Cloudformation template :
HttpApi:
Type: AWS::ApiGatewayV2::Api
Properties:
Body:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: "s3://XXXX/Swagger.yml"
But It has following error in cloudformation :
"Transform AWS::Include failed with: The specified S3 object's content should be valid Yaml/JSON"
And when I remove built-in functions like Join and GetAtt from my swagger.yml it works.
Related
I have made a SAM template that deploys a mix of public and authenticated endpoints. The default auth is oauth. For public endpoints, I use overrides to make it auth NONE. This worked fine.
After I have added the OpenAPI for documentation. The auth override for public endpoints does not work anymore. What else should I do?
#sam-template.yaml
Resources:
RestApi:
Type: AWS::Serverless::Api
Properties:
Name: !Ref ApiStackName
StageName: Prod
Auth:
AddDefaultAuthorizerToCorsPreflight: false
DefaultAuthorizer: TokenAuthorizer
Authorizers:
TokenAuthorizer:
FunctionArn: !GetAtt Authorizer.Arn
Identity:
Header: Authorization
ValidationExpression: Bearer.*
ReauthorizeEvery: 0
DefinitionBody: // this is what I added.
Fn::Transform:
Name: AWS::Include
Parameters:
Location:
Fn::Join:
- ''
- - 's3://'
- Ref: S3BucketName
- '/swagger.yaml'
GetFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./functions
FunctionName: !Sub ${Environment}-api-get
Description: get
Handler: ./src/get.handler
Role: !Sub arn:aws:iam::${AWS::AccountId}:role/pam-${Environment}-${AWS::Region}-get-lambda-role
Events:
Api:
Type: Api
Properties:
RestApiId: !Ref RestApi
Path: /p
Method: GET
Auth:
Authorizer: NONE // this overrides the default auth
#swagger.yaml
/p:
get:
summary: Get
description: Get
responses:
200:
description: "200 response"
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/P"
500:
description: "500 response"
content: {}
x-amazon-apigateway-auth:
type: "NONE"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetFunction.Arn}/invocations
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
security: {}
OR
security:
- {}
Didn't work for me.
The below mentioned code snippet worked.
security:
- NONE: []
you are looking for security in OpenAPI. This sets Authorization on ApiGateway endpoint to NONE.
/p:
get:
summary: Get
description: Get
responses:
...
security:
- {}
x-amazon-apigateway-integration:
...
I have an AWS SAM template, which creates lambda function and post method in API Gateway. By default, it uses Lambda Proxy integration and it is working fine when I am testing through the PostMan tool but when I am using the API gateway URL with my sandbox app, it is displaying the following error.
Access to XMLHttpRequest at 'https://abcdef.execute-api.eu-west-2.amazonaws.com/dev/my-api' from origin 'https://abcd.csb.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
but when I am creating API gateway post method manually and trying then it is working fine.
Lambda function also returning following header in the response.
response = {
'statusCode': status_code,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST'
},
'body': json.dumps(response_data)
}
Following is AWS SAM template.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
AWS SAM Template
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 10
Parameters:
DeploymentEnv:
Type: String
Resources:
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
EndpointConfiguration:
Type: REGIONAL
Cors:
AllowMethods: "'POST,OPTIONS'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
AllowOrigin: "'*'"
MaxAge: "'600'"
AllowCredentials: false
Auth:
DefaultAuthorizer: NONE
ApiKeyRequired: true # sets for all methods
LambdaFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
FunctionName: !Join [ "", [ !Ref DeploymentEnv, "-my-lambda"]]
CodeUri: my_api/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
EventTriggerlambda:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /my-api
Method: POST
Auth:
ApiKeyRequired: true
Role: Role_URN
Environment:
Variables:
URI: Test
USER_NAME: Test
PASSWORD: Test
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn: ApiGatewayApiStage
Properties:
Name: !Join ["", [{"Ref": "AWS::StackName"}, "-apikey"]]
Enabled: true
StageKeys:
- RestApiId: !Ref ApiGatewayApi
StageName: !Ref DeploymentEnv
UsagePlan:
DependsOn:
- ApiGatewayApiStage
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId: !Ref ApiGatewayApi
Stage: !Ref DeploymentEnv
Throttle:
BurstLimit: 500
RateLimit: 100
UsagePlanName: MY-UsagePlan
UsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref ApiKey
KeyType: API_KEY
UsagePlanId: !Ref UsagePlan
Outputs:
LambdaFunction:
Description: "Lambda Function ARN"
Value: !GetAtt LambdaFunction.Arn
Please help, Thanks :)
Configuration is not proper for API creation in API-Gateway in the AWS SAM template. because SAM deployment uses lambda proxy integration by default that's why in method response, there are few values required which can not be set automatically using the above configuration. So I use open API specification where I defined Rest API configuration and it is working fine without any manual intervention after deployment.
Following configuration is fine.
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location: !Join [ '', [ 's3://mybucket', '/openapi-spec.yaml' ] ]
EndpointConfiguration:
Type: REGIONAL
OpenAPi Configuration
openapi: "3.0.1"
info:
title: "test-api"
description: "Created by AWS Lambda"
version: "2022-01-07T18:00:40Z"
paths:
/test-api:
post:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
httpMethod: "POST"
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: "when_no_match"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
options:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
Access-Control-Allow-Methods:
schema:
type: "string"
Access-Control-Allow-Headers:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
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-Origin: "'*'"
requestTemplates:
application/json: "{\"statusCode\": 200}"
passthroughBehavior: "when_no_match"
type: "mock"
x-amazon-apigateway-any-method:
responses:
"200":
description: "200 response"
content: {}
security:
- api_key: []
x-amazon-apigateway-integration:
httpMethod: "POST"
uri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunction.Arn}/invocations"
responses:
".*":
statusCode: "200"
passthroughBehavior: "when_no_match"
type: "aws_proxy"
components:
schemas:
Empty:
title: "Empty Schema"
type: "object"
securitySchemes:
api_key:
type: "apiKey"
name: "x-api-key"
in: "header"
here openapi-spec.yaml file was kept in the same folder as the AWS SAM template and it was uploaded to the S3 bucket before deployment start using the following command in the GitHub workflow pipeline file.
- run: aws s3 cp openapi-spec.yaml s3://mnai-code-deployments
- run: sam build
- run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --stack-name my-stack --s3-bucket mybucket --capabilities CAPABILITY_IAM --region eu-west-2 --parameter-overrides ParameterKey=DeploymentEnv,ParameterValue=dev ParameterKey=S3Bucket,ParameterValue=mybucket
Thanks
Here is a CloudFormation puzzle I think I cannot solve without your help. I'm trying to create a template for a REST API with CloudFormation (YAML). The API has a Lambda Proxy and has to have a MethodResponse as shown in the attached image.
This is my template so far which produces the following error when building the stack:
PostMethod: Value of property ResponseParameters must be an
object
ApiGatewayAccount:
Type: "AWS::ApiGateway::Account"
Properties:
CloudWatchRoleArn: "some role"
RestApi:
Type: "AWS::ApiGateway::RestApi"
Properties:
Description: "some rest api"
EndpointConfiguration:
Types:
- REGIONAL
Name: RestApi
SomeResource:
Type: "AWS::ApiGateway::Resource"
Properties:
ParentId:
Fn::GetAtt:
- "RestApi"
- "RootResourceId"
PathPart: part
RestApiId:
Ref: "RestApi"
SomeSubResource:
Type: "AWS::ApiGateway::Resource"
Properties:
ParentId:
Ref: "SomeResource"
PathPart: count
RestApiId:
Ref: "RestApi"
SomeResponseModel:
Type: "AWS::ApiGateway::Model"
Properties:
ContentType: "text/html"
Description: "Empty text/html response."
Name: someresponse
RestApiId:
!Ref RestApi
Schema: {}
PostMethod:
Type: "AWS::ApiGateway::Method"
Properties:
HttpMethod: POST
Integration:
IntegrationHttpMethod: POST
Type: AWS_PROXY
Uri:
Fn::Join:
- ""
- - "arn:aws:apigateway:"
- "some-region"
- ":lambda:path/2015-03-31/functions/"
- "some-arn-of-lambda-function"
MethodResponses:
-
ResponseModels:
Key: "application/x-www.form-urlencoded"
Value:
!Ref SomeResponse
ResponseParameters:
- method.response.header.Content-Length: true
- method.response.header.Content-Type: true
- method.response.header.Connection: true
StatusCode: 200
OperationName: SomeName
ResourceId:
!Ref "SomeSubResource"
RestApiId:
!Ref "RestApi"
According to the documentation, it would seem that this should not be a list of key-value pairs, but instead just an object, where each entry is just another key/value.
I expect the following would work:
ResponseParameters:
method.response.header.Content-Length: true
method.response.header.Content-Type: true
method.response.header.Connection: true
We are currently using API Keys to secure access to our API Gateway. However, we are moving to an IAM model with access/secret key. I understand that swagger does not allow us to do this (we currently have api_key set in swagger to enable API Key authentication).
I have created the policy needed for the various operations as:
SvcAccountPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub 'iam-${EnvTag}'
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'execute-api:Invoke'
Resource:
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/GET/*'
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/POST/*'
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/PUT/*'
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/DELETE/*'
Users:
- !Ref userSvcAcct
My lambda function is shown below. I am still new to cloud formation, and would love some help on what I can do to add a lambda authorizer to this ( I believe it will be in the Events->ApiPost/Get etc section), that would allow me to use secret/access key.
FtpUserMgmtLambda:
Type: AWS::Serverless::Function
Properties:
Description: Lambda handler function for FTP user management
Handler: 'handler.UserManagementHandler::handleRequest'
Runtime: java8
MemorySize: 512
Timeout: 300
FunctionName: !Ref LambdaFunctionName
Role: !GetAtt UserMgmtLambdaRole.Arn
CodeUri:
Bucket: !Ref LambdaCodeS3Bucket
Key: !Ref LambdaCodeFileName
VpcConfig:
SomeConfig stuff here
Environment:
Variables:
dbPort: !Ref UserStoreDbPort
dbUser: !Ref UserStoreDbUserId
dbName: !Ref UserStoreDbName
environment: !Ref EnvTag
basepath: 'somepath'
Events:
ApiPost:
Type: Api
Properties:
RestApiId: !Ref SomeApi
Path: /path
Method: POST
Auth: <<Dont know what to do here! HELP>>
ApiGet:
Type: Api
Properties:
RestApiId: !Ref SomeApi
Path: /path
Method: GET
Auth: *<<Dont know what to do here! HELP>>*
Tags:
Name: !Ref LambdaFunctionName
function: lambda function that manages ftp users
Fixed this through Swagger. Example code as under:
---
swagger: "2.0"
info:
version: "2017-10-17T17:47:44Z"
title: "User-Mgt-API"
basePath: "/${environment}"
schemes:
- "https"
paths:
/ftpuser:
post:
x-amazon-apigateway-auth:
type: aws_iam
produces:
- "application/json"
responses:
200:
description: "When create user request successful"
schema:
$ref: "#/definitions/Empty"
400:
description: "When API vallidation error happens"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${FtpUserMgmtLambda.Arn}/invocations
passthroughBehavior: "when_no_match"
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
definitions:
Empty:
type: "object"
title: "Empty Schema"
Then in the cloudformation, added the following to the serverless API definition to process the swagger file. Of course,
FtpUserMgmtApi:
Type: AWS::Serverless::Api
Properties:
Name: !Ref ApiName
StageName: !Ref ApiDeploymentStageName
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: !Sub s3://${swaggerS3Location}
Hope this helps. There is also an example on the web to use x-amazon-apigateway-any-method using which I derived the above. That link is here.
I want to integrate Cognito token in my application.
How can i do it in AWS Sam Template ?
To update my template, I look on https://docs.aws.amazon.com/fr_fr/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html?shortFooter=true
Info:
My UserPool is created in the AWS console (on web)
I test with Postman without header: if it worked I should be refused ==> reallity: I have results (my Authorizer doesn't work)
=========================
My question is : why Authorizer doesn't work ?
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Globals:
Function:
Runtime: nodejs6.10
Handler: index.handler
Timeout: 30
Resources:
GRApi:
Type: 'AWS::Serverless::Api'
Properties:
Name: 'Myname'
StageName: !Ref Stage
Cors: "'*'"
EndpointConfiguration: REGIONAL
DefinitionBody:
swagger: "2.0"
info:
version: "1.0"
title: "myTitle"
host: !Ref Host
securityDefinitions:
cognitoUserPool:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: cognito_user_pools
x-amazon-apigateway-authorizer:
type: cognito_user_pools
providerARNs:
- "arn:aws:cognito-idp..."
schemes:
- "https"
consumes:
- application/json
produces:
- application/json
paths:
/project:
get:
responses: {}
security:
- cognitoUserPool: []
x-amazon-apigateway-integration:
uri:
- 'arn:aws:apigateway:....Arn'
passthroughBehavior: "when_no_match"
httpMethod: "POST"
type: "aws_proxy"
GetAllProjectsFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: URI/
Handler: index.handler
Runtime: nodejs8.10
MemorySize: 128
Timeout: 30
Role: 'arn:....role'
Events:
GetAllProjects:
Type: Api
Properties:
Path: /project
Method: get
RestApiId: !Ref GRApi
Outputs:
...