Set the HTTP Endpoint URL value for REST API from AWS CDK - amazon-web-services

I am trying to have a serviceHost stage variable to be set for each request from API GATEWAY, exactly like picture attached below.
According to doc https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-set-stage-variables-aws-console.html we can have something like this from console, but since my app is totally on CDK so just wanted to figure out a way to have it configured through CDK itself.
Couldn't find that in https://docs.aws.amazon.com/cdk/api/latest/docs/#aws-cdk_aws-apigateway.IntegrationOptions.html or anywhere.
Is it possible to attain through CDK somehow.

You can set the stage variables when declaring a stage. As per the documentation:
import aws_cdk.aws_apigateway
my_stage = aws_cdk.aws_apigateway.Stage(
self,
"my_stage",
variables = {"serviceHost": "my_value"}
)

Related

API gateway proxy integration with lambda function in CDK

When I set CDK as following , and deploy them. the two content was generated in api gateway.
new LambdaRestApi(this,"api",{
handler:lambdaFunction
});
I totally beginner this kind of API manipulation and have questions.
① what is {proxy+} ?
② what is the difference between following two API ?
③ How can I see payload which will be passed to lambda function ?
If someone has opinion or materials please let me know.
Thanks
The purpose of the proxy+ is to enable the following URLs to work with your function:
https://44444.execute-api.gggg.amazonaws.com/test-invoke-stage/some/path1/path3
https://44444.execute-api.gggg.amazonaws.com/test-invoke-stage
https://44444.execute-api.gggg.amazonaws.com/test-invoke-stage/test/gggg
https://44444.execute-api.gggg.amazonaws.com/test-invoke-stage/test/5
without proxy+ only the following will work:
https://44444.execute-api.gggg.amazonaws.com/test-invoke-stage
So the proxy+ is able to accept everything past /test-invoke-stage as it matches every path starting with /test-invoke-stage.

List all LogGroups using cdk

I am quite new to the CDK, but I'm adding a LogQueryWidget to my CloudWatch Dashboard through the CDK, and I need a way to add all LogGroups ending with a suffix to the query.
Is there a way to either loop through all existing LogGroups and finding the ones with the correct suffix, or a way to search through LogGroups.
const queryWidget = new LogQueryWidget({
title: "Error Rate",
logGroupNames: ['/aws/lambda/someLogGroup'],
view: LogQueryVisualizationType.TABLE,
queryLines: [
'fields #message',
'filter #message like /(?i)error/'
],
})
Is there anyway I can add it so logGroupNames contains all LogGroups that end with a specific suffix?
You cannot do that dynamically (i.e. you can't make this work such that if you add a new LogGroup, the query automatically adjusts), without using something like AWS lambda that periodically updates your Log Query.
However, because CDK is just a code, there is nothing stopping you from making an AWS SDK API call inside the code to retrieve all the log groups (See https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudWatchLogs.html#describeLogGroups-property) and then populate logGroupNames accordingly.
That way, when CDK compiles, it will make an API call to fetch LogGroups and then generated CloudFormation will contain the log groups you need. Note that this list will only be updated when you re-synthesize and re-deploy your stack.
Finally, note that there is a limit on how many Log Groups you can query with Log Insights (20 according to https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html).
If you want to achieve this, you can create a custom resource using AwsCustomResource and AwsSdkCall classes to do the AWS SDK API call (as mentioned by #Tofig above) as part of the deployment. You can read data from the API call response as well and act on it as you want.

How to get bucket name from Bucket object in AWS CDK for python

I've create an S3 bucket for hosting my website. For that I've used the below code from the AWS CDK for python docs
self.bucket = s3.Bucket(
self,
"my-bucket-name",
bucket_name="my-bucket-name",
removal_policy=core.RemovalPolicy.DESTROY,
website_index_document="index.html",
public_read_access=True
)
For a reason, I want to send this bucket object as an argument to another object and get the bucket name from the argument. So, I've tried
self.bucket.bucket_name
self.bucket.bucket_arn
nothing seems working, instead the object returns ${Token[TOKEN.189]}. Could anyone guide me through this?
If the bucket name is hard coded like the example you pasted above, you can always externalize it to the cdk context file. As you've seen, when you access the bucket name from the Bucket construct, it creates a reference to it and that is so if you need it in another resource, cloud formation will depend on the value from the Bucket resource by using the Ref/GetAtt capabilities in CloudFormation. Then it will be guaranteed that the bucket actually exists before it is used downstream.
If you don't care about that and just want the actual bucket name in the cdk app code then put the value in the cdk context json file and use node.try_get_context to retrieve it wherever.
There is a handy method called fromBucketName you can use if it wasn't defined in your current app:
const bucket = aws_s3.Bucket.fromBucketName(this, 'bucketLabel", "nameYouGaveBucket")
Otherwise, I believe you are looking for bucket.bucketName (typescript) or bucket.bucket_name (python).
See typescript docs python docs. This is also available in the CDK wrappers in other languages.
Note that there are similar methods for all sorts of CDK constructs, so you should refer often to the API docs, as there is lots like this you can find easily there.

Dynamic Stage Variables in AWS API Gateway

How can I set stageVariables via request headers or query string
parameters in API Gateway?
I have added a stageVariable to the lambda function name in the integration request. When I set the stage variable fixed in the stage this does work.
However, when I try to set the variable via a query string I get a server error.
How can I set a lambda version in an API request dynamically?
I think Stage Variables are just that - they vary on stage, and nothing else. If there's a way of mapping a query parameter into a stage variable I'd like to know about it - but I think it's not possible.

InvalidSignatureException when using boto3 for dynamoDB on aws

Im facing some sort of credentials issue when trying to connect to my dynamoDB on aws. Locally it all works fine and I can connect using env variables for AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION and then
dynamoConnection = boto3.resource('dynamodb', endpoint_url='http://localhost:8000')
When changing to live creds in the env variables and setting the endpoint_url to the dynamoDB on aws this fails with:
"botocore.exceptions.ClientError: An error occurred (InvalidSignatureException) when calling the Query operation: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
The creds are valid as they are used in a different app which talks to the same dynamoDB. Ive also tried not using env variables but rather directly in the method but the error persisted. Furthermore, to avoid any issues with trailing spaces Ive even used the credentials directly in the code. Im using Python v3.4.4.
Is there maybe a header that also should be set that Im not aware of? Any hints would be apprecihated.
EDIT
Ive now also created new credentials (to make sure there are only alphanumerical signs) but still no dice.
You shouldn't use the endpoint_url when you are connecting to the real DynamoDB service. That's really only for connecting to local services or non-standard endpoints. Instead, just specify the region you want:
dynamoConnection = boto3.resource('dynamodb', region_name='us-west-2')
It sign that your time zone is different. Maybe you can check your:
1. Time zone
2. Time settings.
If there are some automatic settings, you should fix your time settings.
"sudo hwclock --hctosys" should do the trick.
Just wanted to point out that accessing DynamoDB from a C# environment (using AWS.NET SDK) I ran into this error and the way I solved it was to create a new pair of AWS access/secret keys.
Worked immediately after I changed those keys in the code.