Serverless - Referencing api gateway address in CloudFront origin definition - aws-cloudformation

Using Serverless Framework,
i am creating an api gateway in my template :
functions
test:
handler: test.handler
events:
- http:
path: save-subscription
method: post
cors: false
later on i want to use this api address xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/
as a domain name of an oigin of my cloudfront origins
DomainName: xxxxxxx.execute-api.us-east-1.amazonaws.com
OriginPath: dev
Is there a way to reference the api address dynamically/programmatically before it even exist, and do I need to use depends on?
Thanks

- DomainName:
Fn::Join:
- ""
- - "Ref": "ApiGatewayRestApi"
- ".execute-api.${self:custom.region}.amazonaws.com"
worked for me.
Found the answer here : https://www.richdevelops.dev/blog/how-do-i-get-my-api-gateway-url

Related

Google API Gateway OpenApi Swaagger 2.0 to CloudRun Parameter configured for Path turns out in query instead of path

I'm testing an API Gateway setup on Google Cloud to access specific endpoints on a service deployed on Cloud Run. I'm following the steps shown here. We need to authenticate using an API Key, so the API Key specific configuration that went into the API Gateway config was picked from this documentation.
The API Gateway config is as shown below:
# api_gateway_config.yaml
swagger: '2.0'
info:
title: myappapi
description: API with Cloudrun Backend
version: 1.0.0
schemes:
- https
produces:
- application/json
paths:
/:
get:
summary: Greet a User from service
operationId: hello
x-google-backend:
address: https://myappapi-asldfjoiewjfv-uc.a.run.app/
security:
- api_key: []
responses:
'200':
description: A successful response
schema:
type: string
/reports/results/{id}:
get:
summary: Get Report Results for specified report id
operationId: GetReportResults
x-google-backend:
address: https://myappapi-asldfjoiewjfv-uc.a.run.app/v1/reports/results/{id}
parameters:
- in: path
name: id
required: true
type: integer
security:
- api_key: []
responses:
'200':
description: A successful response
schema:
type: string
securityDefinitions:
# This section configures basic authentication with an API Key.
api_key:
type: "apiKey"
name: "key"
in: "query"
For a sample call to the /reports/results endpoint as http://myappapi/reports/results/1,
the expectation is for calls to get converted to https://myappapi-asldfjoiewjfv-uc.a.run.app/v1/reports/results/1?key=MyAPIKeyHere. But instead they turn out as https://myappapi-asldfjoiewjfv-uc.a.run.app/v1/reports/results?key=MyAPIKeyHere&id=1
Is there a way to get the API calls go as https://myappapi-asldfjoiewjfv-uc.a.run.app/v1/reports/results/1?key=MyAPIKeyHere ?
Thanks in Advance!
As mentioned in this documentation
Set path_translation as part of setting x-google-backend:
x-google-backend:
address: https://GCP_REGION-PROJECT_ID.cloudfunctions.net/hello
path_translation: [ APPEND_PATH_TO_ADDRESS | CONSTANT_ADDRESS ]
The default value of path_translation depends on where you set x-google->backend in your OpenAPI spec:
When x-google-backend is used at the top level of the OpenAPI specification, path_translation defaults to APPEND_PATH_TO_ADDRESS.
When x-google-backend is used at the operation level of the OpenAPI specification, path_translation defaults to CONSTANT_ADDRESS.
For more details on path translation, please see the Understanding path translation section. You can also check this stackoverflow thread.

Getting cors error when api gateway deployed using SAM template

I have developed lambda functions in node.js and trying to deploy to api gateway with proxy integration using SAM templates.
my lambda functions are returning headers as mentioned in AWS documentation
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "https://www.example.com",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
body: JSON.stringify('Hello from Lambda!'),
};
template.yaml code
GetClientFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: functions/GetClient/
Handler: index.handler
Runtime: nodejs14.x
Events:
GetClientCustomFieldMap:
Type: Api
Properties:
RestApiId: !Ref ClientApi # this is api with authorizer configured
Path: api/Client/GetClient/{name}
Method: get
It is creating all resources which mentioned in the path like 'api', 'Client', 'GetClient' but not with Options method, also getting cors error. Tried multiple ways from stackoverflow but could not resolve it.
Followed this url as well How to enable CORS with AWS SAM
You need to configure Cors of the Api resource for the OPTIONS methods, see https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html#sam-api-cors

AWS Lambda Access to XMLHttpRequest at '…' from origin 'localhost:3000' has been blocked by CORS policy

I know this question might be duplicated, but none of the existing question point to anything I'm not doing...
I've deployed an API using the serverless framework on AWS Lambda, but I'm having trouble with CORS.
I'm doing a get request using API module from aws-amplify in a react frontend:
async function getProfileItem() {
return API.get('profile', '/getProfileItem', {
body: {
emailId: emailId
}
});
}
and I am getting the below error when calling the endpoint:
Access to XMLHttpRequest at 'https://xxxx.execute-api.region.amazonaws.com/prod/getProfileItem' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
I have created three endpoints so far to create, update and get but its only the get endpoint that is not working!!
Below is relevant part of my serverless.yml:
functions:
create:
handler: create.main
events:
- http:
path: createProfile
method: post
cors: true
authorizer: aws_iam
get:
handler: get.main
events:
- http:
path: getPofileItem
method: get
cors: true
authorizer: aws_iam
update:
handler: update.main
events:
- http:
path: profile/flipPhotoFlag
method: put
cors: true
authorizer: aws_iam
Not posting my backend code since the request is not even hitting the backend and is just failing in the browser. Any clue why this might be happening with only get method while the create and update are working just fine?

As 'host' is deprecated for manifest.yml - how to configure a standard scapp.io route?

CF CLI now warns with a deprecation message:
Deprecation warning: Route component attributes 'domain', 'domains', 'host', 'hosts' and 'no-hostname' are deprecated. Found: host.
My manifest.yml looks like that currently:
applications:
- host: myexample-test
which results in a final route like: myexample-test.scapp.io
how to define this exact same route with the new manifest routes config?
These examples are taken from the cloudfoundry docs but I am not sure whether swisscomdev is adopting anything behind the scenes?
routes:
- route: example.com
- route: www.example.com/foo
- route: tcp-example.com:1234
UPDATE
Just tried it with suggested solution and this manifest:
applications:
routes:
- route: myexample-test.scapp.io
name: MyExample
buildpack: nodejs_buildpack
instances: 1
memory: 64M
which resulted in the following error message:
yaml: unmarshal errors:
line 2: cannot unmarshal !!map into []manifest.Application
Swisscom Application cloud does not do something special behind the scenes, so you can apply what's written in the CF CLI docs.
If we're doing something other than vanilla CF, we will mention this in our docs.
I quickly checked it, the following does the trick for your route:
routes:
- route: myexample-test.scapp.io
In your example, note that applications must be an array of maps, so make sure the first element key contains a -, otherwise it's treated as a map.
Full example:
applications:
- name: MyExample
routes:
- route: myexample-test.scapp.io
buildpack: nodejs_buildpack
instances: 1
memory: 64M

CloudFormation to Configure API Gateway Method to use Cognito Authorizer

I'm trying to define API Gateway resources using CloudFormation. Specifically, I'm attempting to create a template for an API Gateway Resource Method that authenticates using Cognito. I've created the Authorizer, and using the console I can perform this configuration without issue (see image attached). I just can't find a way to specify the API method request authorization using the Cognito user pool. It's driving me crazy. As far as I can see, no documentation covers this.
Does anyone know if this is possible, and if so, how to do it? I realize I can achieve this using Swagger but I'm not looking forward to re-defining all of my API Gateway resources in Swagger vs. CloudFormation.
Thanks in advance!
If you are using SAM then you set the pool as a global default and mark the functions you don't want to be authenticated.
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Cors: "'*'"
Auth:
DefaultAuthorizer: MyCognitoAuthorizer
Authorizers:
MyCognitoAuthorizer:
UserPoolArn: !GetAtt MyCognitoUserPool.Arn
MyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src
Handler: lambda.handler
Runtime: nodejs8.10
Events:
Root:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /
Method: GET
MyCognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: !Ref CognitoUserPoolName
Policies:
PasswordPolicy:
MinimumLength: 8
UsernameAttributes:
- email
Schema:
- AttributeDataType: String
Name: email
Required: false
MyCognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
UserPoolId: !Ref MyCognitoUserPool
ClientName: !Ref CognitoUserPoolClientName
GenerateSecret: false
For functions you don't want to be behind cognito. Define in the events section of the AWS::Serverless::Function definition.
Events:
Root:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /
Method: GET
Auth:
Authorizer: 'NONE'
Use the AWS Sam template documentation rather than the cloudformation definitions.
I don't have a code sample handy, but here's what you will need to do:
1) Add an Authorizer resource to your template with type "COGNITO_USER_POOLS",
2) Set the authorizerId on the API method resource to the ID reference from the authorizer. Set the authorizationType on the method to "COGNITO_USER_POOLS"
As for the user pools themselves, you will need to use custom resources, at least until official support is released. There are several open-source implementations out there that you could use (here's one example: https://github.com/aws-samples/aws-api-gateway-developer-portal/tree/7d0d1e56d54e9775ee2d18907ebdf1db9dafcc06/lambdas/cognito-cloudformation-custom-resource)