Update apigateway deployment with cli - amazon-web-services

How do I update a apigateway deployment using the cli? I can find the update-deployment command, but I do not know what to put in for the values it needs in this skeleton (taken from the documentation):
{
"op": "add"|"remove"|"replace"|"move"|"copy"|"test",
"path": "string",
"value": "string",
"from": "string"
}

update-deployment is used to update the metadata of an existing deployment. For example, to update the description of a deployment:
aws apigateway update-deployment \
--rest-api-id <value> \
--deployment-id <value> \
--patch-operations 'op=replace,path=/description,value=<value>'
If you wanted to re-deploy an API (this is what happens when you click on "Deploy API" in the web console), you'd use the create-deployment command:
aws apigateway create-deployment \
--rest-api-id <value> \
--stage-name <value>

Related

How to change AWS API Gateway method integration type to HTTP_PROXY with CLI?

In my case, AWS API Gateway should proxy every request and response through as they are. The API was created by importing an OpenAPI definition. I know how to manually set the method integration in the AWS console to HTTP proxy and set the endpoint URI.
I want to get rid of manual work and create a PowerShell script that loops through every method and sets those settings. But I haven't found the right command to update the integration type and URI.
After reading AWS CLI reference I have tried this command:
update-integration --rest-api-id x0cm5muxxx --resource-id xvxxxx --http-method GET --integration-type HTTP_PROXY --profile user2
But it gives an error:
"Unknown options: --integration-type, HTTP_PROXY"
Another CLI command I have tried without success is update-method with --patch-operations.
After the changes, the method's integration should look like this example:
PS C:\WINDOWS\system32> aws apigateway get-integration --rest-api-id x0cm5muxxx --resource-id x1lxxx --http-method GET --profile user2
{
"type": "HTTP_PROXY",
"httpMethod": "GET",
"uri": "https://${stageVariables.Url}/api/v1/Productlist/CanOrder/{fnprodId}",
"connectionType": "INTERNET",
"requestParameters": {
"integration.request.path.fnprodId": "method.request.path.fnprodId"
},
"passthroughBehavior": "WHEN_NO_MATCH",
"timeoutInMillis": 29000,
"cacheNamespace": "01lxxx",
"cacheKeyParameters": [],
"integrationResponses": {
"200": {
"statusCode": "200"
}
}
}
The next problem will be how to loop through every single method in the API for this update.
I got help and correct command to change methods integration type is:
aws apigateway put-integration --rest-api-id $RestAPIid --resource-id $ResourceId --http-method GET --type HTTP_PROXY --integration-http-method GET --profile $Profile --uri $uri
If someone is trying to loop Rest API resources with Powershell it goes like this simplified..
$array = Aws apigateway get-resources --rest-api-id $RestAPIid --profile $MyProfile --query [items[*].id]
$array | sort
"Resources:"
$array
""
"Amount of resources:"
echo $array.Length
""
foreach ($arrayItem in $array) {
"$arrayItem = " + $arrayItem.length
}

AWS EventBridge discards request headers and parameters for scheduled API Destinations calls using Localstack

I am using Localstack in local environment to schedule cron calls every minute to a dummy POST endpoint (using https://webhook.site/) which works fine. However, only the body is kept (from put-targets, not from create-connection) but the request headers, query string parameters and path parameters are all discarded. Whether I test this with AWS CLI or with a Golang example (just to confirm the issue), the issue still persist. Just wondering if anyone has come across with such issue before or am I missing something? As the documentation states we could set these info on both Connection and Targets which I did just in case with both.
Localstack
version: "2.1"
services:
localstack:
image: "localstack/localstack"
container_name: "localstack"
ports:
- "4566-4599:4566-4599"
environment:
- DEBUG=1
- DEFAULT_REGION=eu-west-1
- SERVICES=events
- DATA_DIR=/tmp/localstack/data
- DOCKER_HOST=unix:///var/run/docker.sock
- LAMBDA_EXECUTOR=docker
volumes:
- "/tmp/localstack:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
CLI example
Create rule
aws --profile localstack --endpoint-url http://localhost:4566 events put-rule \
--name http-api-cron-rule \
--schedule-expression "cron(* * * * *)"
{
"RuleArn": "arn:aws:events:eu-west-1:000000000000:rule/http-api-cron-rule"
}
Create connection
aws --profile localstack --endpoint-url http://localhost:4566 events create-connection \
--name http-api-connection \
--authorization-type Basic \
--auth-parameters "{\"BasicAuthParameters\":{\"Username\":\"hello\",\"Password\":\"world\"},\"InvocationHttpParameters\":{\"HeaderParameters\":[{\"Key\":\"hdr\",\"Value\":\"val\",\"IsValueSecret\":false}],\"QueryStringParameters\":[{\"Key\":\"qry\",\"Value\":\"val\",\"IsValueSecret\":false}],\"BodyParameters\":[{\"Key\":\"bdy\",\"Value\":\"val\",\"IsValueSecret\":false}]}}"
{
"ConnectionArn": "arn:aws:events:eu-west-1:000000000000:connection/http-api-connection/4c6a29cf-4665-41f1-b90f-a43e41712e5e",
"ConnectionState": "AUTHORIZED",
"CreationTime": "2022-01-07T17:24:57.854127+00:00",
"LastModifiedTime": "2022-01-07T17:24:57.854127+00:00"
}
Create destination
Obtain a URL from https://webhook.site first and use below.
aws --profile localstack --endpoint-url http://localhost:4566 events create-api-destination \
--name http-api-destination \
--connection-arn "arn:aws:events:eu-west-1:000000000000:connection/http-api-connection/4c6a29cf-4665-41f1-b90f-a43e41712e5e" \
--http-method POST \
--invocation-endpoint "https://webhook.site/PUT-YOUR-OWN-UUID-HERE"
{
"ApiDestinationArn": "arn:aws:events:eu-west-1:000000000000:api-destination/http-api-destination/c582470b-4413-4dba-bde9-e7d1aef64ac9",
"ApiDestinationState": "ACTIVE",
"CreationTime": "2022-01-07T17:27:27.608361+00:00",
"LastModifiedTime": "2022-01-07T17:27:27.608361+00:00"
}
Create target
aws --profile localstack --endpoint-url http://localhost:4566 events put-targets \
--rule http-api-cron-rule \
--targets '[{"Id":"1","Arn":"arn:aws:events:eu-west-1:000000000000:api-destination/http-api-destination/c582470b-4413-4dba-bde9-e7d1aef64ac9","Input":"{\"bdyx\":\"val\"}","HttpParameters":{"PathParameterValues":["parx"],"HeaderParameters":{"hdrx":"val"},"QueryStringParameters":{"qryx":"val"}}}]'
{
"Targets": [
{
"Id": "1",
"Arn": "arn:aws:events:eu-west-1:000000000000:api-destination/http-api-destination/c582470b-4413-4dba-bde9-e7d1aef64ac9",
"Input": "{\"bdyx\":\"val\"}",
"HttpParameters": {
"PathParameterValues": [
"parx"
],
"HeaderParameters": {
"hdrx": "val"
},
"QueryStringParameters": {
"qryx": "val"
}
}
}
]
}
Logs
localstack | DEBUG:localstack.services.events.events_listener: Notifying 1 targets in response to triggered Events rule http-cron-rule
localstack | DEBUG:localstack.utils.aws.message_forwarding: Calling EventBridge API destination (state "ACTIVE"): POST https://webhook.site/your-uuid-goes-here

How to Create an API with VPC Link Integration for EKS?

I have a working EKS Cluster with some services running in there. The challenge right now, is to have an API gateways to call those services. That is why I started reading "Integrate Amazon API Gateway with Amazon EKS" explaining that this is possible but there are some steps to do in order to make this work. This is what I did but after some progress, I ran into an issue.
Here is one of the command-line statements I executed.
aws apigatewayv2 get-vpc-links --region $AGW_AWS_REGION
This results in the following output:
Apparently, the VPC link is available, a security group Id is available, two SubnetIds are available (in the documented example it is three but that should not matter so much, feel free to comment about this) and the status message says that the available VPC link is ready to route traffic.
There for I decided to continue with the next documented step:
Create an API with VPC Link integration
cat > apigw-api.yaml<<EOF
apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
kind: API
metadata:
name: apitest-private-nlb
spec:
body: '{
"openapi": "3.0.1",
"info": {
"title": "ack-apigwv2-import-test-private-nlb",
"version": "v1"
},
"paths": {
"/\$default": {
"x-amazon-apigateway-any-method" : {
"isDefaultRoute" : true,
"x-amazon-apigateway-integration" : {
"payloadFormatVersion" : "1.0",
"connectionId" : "$(kubectl get vpclinks.apigatewayv2.services.k8s.aws \
nlb-internal \
-o jsonpath="{.status.vpcLinkID}")",
"type" : "http_proxy",
"httpMethod" : "GET",
"uri" : "$(aws elbv2 describe-listeners \
--load-balancer-arn $(aws elbv2 describe-load-balancers \
--region $AGW_AWS_REGION \
--query "LoadBalancers[?contains(DNSName, '$(kubectl get service authorservice \
-o jsonpath="{.status.loadBalancer.ingress[].hostname}")')].LoadBalancerArn" \
--output text) \
--region $AGW_AWS_REGION \
--query "Listeners[0].ListenerArn" \
--output text)",
"connectionType" : "VPC_LINK"
}
}
},
"/meta": {
"get": {
"x-amazon-apigateway-integration": {
"uri" : "$(aws elbv2 describe-listeners \
--load-balancer-arn $(aws elbv2 describe-load-balancers \
--region $AGW_AWS_REGION \
--query "LoadBalancers[?contains(DNSName, '$(kubectl get service echoserver \
-o jsonpath="{.status.loadBalancer.ingress[].hostname}")')].LoadBalancerArn" \
--output text) \
--region $AGW_AWS_REGION \
--query "Listeners[0].ListenerArn" \
--output text)",
"httpMethod": "GET",
"connectionId": "$(kubectl get vpclinks.apigatewayv2.services.k8s.aws \
nlb-internal \
-o jsonpath="{.status.vpcLinkID}")",
"type": "HTTP_PROXY",
"connectionType": "VPC_LINK",
"payloadFormatVersion": "1.0"
}
}
}
},
"components": {}
}'
EOF
Unfortunately, this resulted in the following errors:
I tried to isolate the problem but then I ran into another issue. In the command-line, I just executed a small fragment of what is shown above.
aws elbv2 describe-load-balancers --load-balancer-arn --region $AGW_AWS_REGION query "LoadBalancers[?contains(DNSName, '$(kubectl get service authorservice -o jsonpath="{.status.loadBalancer.ingress[].hostname}")')].LoadBalancerArn" --output text
but that resulted in another error:
An error occurred (ValidationError) when calling the
DescribeLoadBalancers operation: 'query' is not a valid load balancer
ARN
So how to get this working? All I want is to just to create an API with VPC link integration. But the documented way to do so does not work for me. Please let me know how I can fix this way or just do the same in a different way.
I am exactly on the same step - trying to create API for micro service on EKS following the same tutorial. I also started to break down the executions to the small chunks to check if things are still correct from the time the tutorial was written.
So taking the smallest piece which should be executable
kubectl get service authorservice -o jsonpath="{.status.loadBalancer.ingress[].hostname}"
You must have the "authorservice" already configured and running or it might be called something else for your particular case.
For me that lines give me back the needed hostname. If it is not giving you the hostname you better check with
kubectl get service <the_service_you_have> -o json
whether the service you have is properly configured and having at the end of the output something similar to
"status": {
"loadBalancer": {
"ingress": [
{
"hostname": "k8s-XXXXXXXXXXXXXXXXXXXXXX.elb.us-west-2.amazonaws.com"
}
]
}
My advice is to go over all the "kubectl" executions and check if they are working and giving back some meaningful results for your case and adjust if needed. At first it might be hard to get where the "kubectl" commands ends but later it gets easy.

The API with ID does not include a resource with path /* having an integration LAMBDA on the ANY method

.net core serverless web api
I am trying to do proxy integration with lambda and api gateway, everything is working fine with aws console
but i am facing issues with aws cli commands
i tried integrating with cli but the lambda is not properly integrated
aws apigateway create-resource --rest-api-id id --parent-id id --path-part {proxy+}
aws apigateway put-method --rest-api-id id --resource-id id --http-method ANY --authorization-type "NONE"
aws apigateway put-integration --rest-api-id id --resource-id id --http-method ANY --type HTTP_PROXY --integration-http-method ANY --uri arn:aws:apigateway:us-east-2:lambda:path//2015-03-31/functions/arn:aws:lambda:us-east-2:account_id:function:helloworld/invocations
aws lambda add-permission --function-name helloworld --action lambda:InvokeFunction --principal apigateway.amazonaws.com --source-arn arn:aws:execute-api:us-east-2:account_id:apiid/*/*/* --statement-id 12345678
There are two problems with your commands -
Incorrect
aws apigateway create-resource --rest-api-id id --parent-id id --path-part {proxy+}
Correct: Notice the double quotes
aws apigateway create-resource --rest-api-id id --parent-id id --path-part "{proxy+}"
Incorrect
aws apigateway put-integration \
--rest-api-id id \
--resource-id id \
--http-method ANY \
--type HTTP_PROXY \
--integration-http-method ANY \
--uri arn:aws:apigateway:us-east-2:lambda:path//2015-03-31/functions/arn:aws:lambda:us-east-2:account_id:function:helloworld/invocations
Correct
type should be AWS_PROXY for Lambda Proxy Integrations.
integration-http-method should always be POST for Lambda Proxy integration, even if the http method is GET or ANY or anything else.
aws apigateway put-integration \
--rest-api-id id \
--resource-id id \
--http-method ANY \
--type AWS_PROXY \
--integration-http-method POST \
--uri arn:aws:apigateway:us-east-2:lambda:path//2015-03-31/functions/arn:aws:lambda:us-east-2:account_id:function:helloworld/invocations

What is the --rest-api-id and --resource-id and where do I find them?

I want to run this command: https://docs.aws.amazon.com/cli/latest/reference/apigateway/test-invoke-method.html
It requires these two fields, but I can't find any docs and where these are:
aws apigateway test-invoke-method --rest-api-id 1234123412 --resource-id avl5sg8fw8 --http-method GET --path-with-query-string '/'
My API gateway endpoint looks like this:
https://abc123.execute-api.us-east-1.amazonaws.com/MyStage/
I only see on unique identifier there - but this command seems to require two IDs. Where do I find them in the API Gateway console?
Your rest-api-id is the identifier before 'execute-api' in your endpoint URL.
In your example URL:
https://abc123.execute-api.us-east-1.amazonaws.com/MyStage/
The rest-api-id is abc123
The resource ID can be obtained with the CLI using the get-resources call and the rest-api-id:
> aws apigateway get-resources --rest-api-id abc123
{
"items": [
{
"id": "xxxx1",
"parentId": "xxxx0",
"pathPart": "foo",
"path": "/foo",
"resourceMethods": {
"GET": {}
}
},
{
"id": "xxxx0",
"path": "/"
}
]}
Each one of the records in the items attribute is a resource, and its id attribute is a resource ID you can use in your test-invoke-method in conjunction with a method that is associated with the resource.
Both values are visible at the top of the console when you select one of your endpoints/resources:
Here is a portion of a bash script that you could use, assuming you have jq installed to parse the json and only one API. It gets the first API ID from the items array, then looks up that Resource ID, then invokes the API using POST:
API_ID=`aws apigateway get-rest-apis | jq -r ".items[0].id"`
RESOURCE_ID=`aws apigateway get-resources --rest-api-id $API_ID | jq -r ".items[].id"`
aws apigateway test-invoke-method --rest-api-id $API_ID --resource-id $RESOURCE_ID --http-method POST