I have been debugging, configuring and you name it the last couple of hours and i can't seem to figure out why this is happening.
I am trying to invoke a lambda function which is just retrieving basic information from ec2. when i test this lambda function in the aws console it seems to be working fine. However, invoking it in another lambda, using following code;
BasicAWSCredentials awsCreds = new BasicAWSCredentials("key1" , "key2");
AWSLambdaClientBuilder builder = AWSLambdaClientBuilder.standard()
.withRegion("eu-west-1")
.withCredentials(new AWSStaticCredentialsProvider(awsCreds));
AWSLambda client = builder.build();
InvokeRequest req = new InvokeRequest()
.withFunctionName("GetWhateverIneed");
InvokeResult result = client.invoke(req);
it simply times out. No response whatsoever... Both Lambdas are connected to the VPC and all subnets
I think it is my new VPC that is causing this problem. My VPC is consisting of:
1 VPC .
-2x Subnets (1x Private with ipv4 10.0.0.0/17, 1x Public with ipv4 10.0.128.0/17).
-1x IGW Connected to the Private subnet.
-1x NAT Gateway connected to the Public subnet .
-2x Endpoints (One for Ec2, One for SecretsManager)
I have also configured two route tables,
One for the "public" subnet:
"Routes" ->
Destination: 10.0.0.0/16 Target: local
Destination: 0.0.0.0/0 Target: My Internet Gateway(IGW)
One for the "private" subnet:
"Routes" ->
Destination: 10.0.0.0/16 Target: local .
Destination: 0.0.0.0/0 Target: My nat
I have made sure both of my Lambdas is running on the same VPC, they are both using the same security group:
This is my first time working with VPC so it is possible that i have missed something.
If your Lambda function is VPC attached, it needs to be able to communicate via your VPC to the AWS API. Lambdas do not talk to other Lambdas over the network, they initiate requests with the AWS API or an API Gateway, which passes the request on to the Lambda Function.
If you need a VPC attached Lambda to initiate another Lambda, it needs to be able to get to the AWS API or API Gateway via the internet. Alternatively, you can keep it all on private networks by adding a VPC Endpoint to the API Gateway Service.
A pattern I follow in similar circumstances is described in this previous post of mine: https://stackoverflow.com/a/43969112/6427978
Related
I'm getting the following error when trying to call create_topic() in Boto3. It works locally in sam running sam local invoke, but once deployed, it times out.
ConnectTimeoutError: Connect timeout on endpoint URL: "https://sns.us-east-2.amazonaws.com/"
Here's the code:
sns = boto3.client('sns')
topic_name = f'my-sns-topic-{ENVIRONMENT}'
topic = sns.create_topic(Name=topic_name)
notification_channel = {"SNSTopicArn": topic["TopicArn"], "RoleArn": "arn:aws:iam::my-role"}
My Lambda function is on private subnets. The function shouldn't require any access to the internet, so I think private subnets are ok (?). All my resources are on the same VPC.
Does the lambda function have to be on a public subnet to reach SNS? I tried adding a 0.0.0.0/0 route mapped to my internet gateway to the route table associated with the private subnet, but that didn't help.
What am I missing?
My Lambda function is on private subnets. The function shouldn't require any access to the internet,
If your lambda function is deployed in a VPC that does not have internet connectivity, then your lambda function will be unable to reach the service endpoint (sns.us-east-2) over the public internet, as you would expect.
If you want private connectivity to the service, then you need to provision a VPC interface endpoint for the service and deploy it in the same VPC as your lambda.
I am trying to produce the correct CDK scripts (TypeScript) to create an environment with a Lambda (accessed via API Gateway) that can call an RDS (Sql Server instance).
I believe I have it mostly working, but I wanted to connect to the RDS instance from my development machine to run some queries and check on a few things.
My RDS instance is in a private subnet, and so I believe in order to connect to it I need to add an Internet Gateway and security group to allow access on the appropriate ports.
For the life of me I can figure out the last piece, how to add the internet gateway using CDK.
The latest script I have tried is as follows:
const privateSubnectConfiguration = {
cidrMask: 26,
name: 'private-subnet',
subnetType: SubnetType.PRIVATE,
};
const publicSubnectConfiguration = {
cidrMask: 26,
name: 'public-subnet',
subnetType: SubnetType.PUBLIC,
};
const vpc = new Vpc(this, props.generateId('vpc'), {
maxAzs: 2,
subnetConfiguration: [privateSubnectConfiguration, publicSubnectConfiguration],
natGateways: 1,
});
vpc.addGatewayEndpoint(props.generateId('internet-gateway'), {
service: { name: "ig-service" }
})
Which then errors with The Vpc Endpoint Service 'ig-service' does not exist (Service: AmazonEC2; Status Code: 400; Error Code: InvalidServiceName;
I see references to the CfnInternetGateway in the docs, but just can't figure out how to attach a new one to my VPC?
Can you please help with the syntax?
First of all, you cannot directly access a database in a private subnet. You have to deploy a proxy instance in your public subnet and forward the required ports to access your database.
When using CDK VPC construct, an Internet Gateway is created by default whenever you create a public subnet. The default route is also setup for the public subnet.
So you should remove addGatewayEndpoint() from your code, which adds a Gateway VPC Endpoint that you don't need.
You may also consider using SubnetType.ISOLATED to create a private subnet without a NAT GW, which may be redundant in your case. SubnetType.PRIVATE creates a NAT Gateway by default.
I want to access a public Rest Api gateway from a AWS Lambda within a VPC.
I already created an execute-api endpoint and added the 443 port to the security group. I also disabled private DNS Names, but I am still getting a "Endpoint request timed out"/ dial tcp 52.28..:443: i/o timeout error.
I also tested the API I want to access with postman, which works as intended.
What am I missing.
By default Lambda in a VPC does not have public internet access.
One option you have is to setup up a NAT gateway in the subnet Lambda is deployed to give it internet access, hence access to public REST API. More here -> Internet access for lambda functions
AWS Lambda uses the VPC information you provide to set up ENIs that allow your Lambda function to access VPC resources. Each ENI is assigned a private IP address from the IP address range within the Subnets you specify, but is not assigned any public IP addresses. Therefore, if your Lambda function requires Internet access (for example, to access AWS services that don't have VPC endpoints ), you can configure a NAT instance inside your VPC or you can use the Amazon VPC NAT gateway. For more information, see NAT Gateways in the Amazon VPC User Guide. You cannot use an Internet gateway attached to your VPC, since that requires the ENI to have public IP addresses.
Or you can have a look here -> Why can't I connect to my public API from an API Gateway VPC endpoint. It suggests this
Use the curl command line tool to test your private API. In your curl command, include the base URL used to invoke the API, as well as a Host header or x-apigw-api-id header. For more information, see Invoking Your Private API Using Endpoint-Specific Public DNS Hostnames.
The base URL to invoke the API includes the DNS name and stage name. It looks like this:
https://vpceId.execute-api.awsRegion.vpce.amazonaws.com/stageName
Note: Replace vpceId with the VPC endpoint ID you copied. Replace awsRegion with your private API's AWS Region (for example, us-east-1). Replace stageName with the name of the stage to which your API is deployed.
The Host header looks like this:
Host:apiId.execute-api.awsRegion.amazonaws.com
Note: Replace apiId with the API ID you copied. Replace awsRegion with your private API's AWS Region (for example, us-east-1).
The x-apigw-api-id header looks like this:
x-apigw-api-id:apiId
Note: Replace apiId with the API ID you copied.
If you set up everything correctly, you get a 200 response code.
try accessing the API using <vpce-id>.execute-api.<region>.vpce.amazonaws.com and passing <api_id>.execute-api.<region>.amazonaws.com in the Host header
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
I am trying to make an outbound API request to a third-party service from within a Lambda function, but the function always times out without any error.
This previously happened when trying to perform a s3.putObject operation within a different function (still within the same VPC / subnets), and I managed to get around that by adding an Endpoint with a service name com.amazonaws.us-east-1.s3 and connecting it to the route table that is associated with the VPC that this Lambda function resides in.
Within the Lambda dashboard inside Network box -> Security Groups section, I see this warning:
When you enable VPC, your Lambda function will lose default internet
access. If you require external internet access for your function,
ensure that your security group allows outbound connections and that
your VPC has a NAT gateway.
I believe that this security group allows outbound connections, based off of the Outbound rules table right underneath:
For that second requirement, I can confirm this VPC has a NAT gateway, because on the VPC Dashboard, within NAT Gateways tab, the one that appears there has a VCP associated with it, and that VPC is the same one hosting the Lambda function.
I followed a guide to create a Flow Log to monitor traffic in and out of the VPC, hoping to see that those outbound requests are indeed rejected. However, after doing so and inspecting the CloudWatch logs, all of the records end in either ACCEPT OK or NODATA.
How can I grant internet access to my VPC Lambda function? is the guide I originally tried to follow, but I got stuck on step 4 under To create a public or private subnet:
From the Change to: drop-down menu, choose an appropriate route table:
For a private subnet, the default route should point to a NAT gateway
or NAT instance:
Destination: 0.0.0.0/0
Target: nat-… (or eni-…)
For a public subnet,
the default route should point to an internet gateway:
Destination: 0.0.0.0/0
Target: igw-…
For all four of the subnets within this VPC, clicking the drop-down to the right of Change to: only showed one option, the one already selected, rtb-xxxxxxxx. After clicking on the link to that route table, and clicking the Routes tab next to Summary, I see this:
What might I be doing wrong that is blocking the Lambda function's access to the Internet?
For Lambda to have access to the internet via VPC it should be in the Private Subnet with NAT Gateway attached.
As per your screenshots, route table attached to subnet has igw-xxxxxxx attached making your current subnet a public subnet.
So to make things work, you can do following:
Attach NAT Gateway instead of igw-xxxxxx in route table of your current subnet
OR
Find ENI attached to your Lambda and attach Elastic IP if you want to have internet access.
OR
As per #John Rotenstein if your Lambda doesnt need VPC recources you can move Lambda out of VPC
I developed a step by step tutorial with explicit screenshots about it:
Part I
Create a lambda function in AWS
Create an API Gateway to redirect all the requests to your AWS Lambda Function
https://medium.com/#shontauro/how-can-i-turn-my-restful-api-into-a-serverless-application-and-deploy-it-to-aws-lambda-step-by-ec7ce38e18be
Part II
Configure a VPC for your lambda function
Grant internet access to the lambda function in a safety way
Deploy the Node.js Restful API into your Lambda Function
https://medium.com/#shontauro/how-can-i-turn-my-restful-api-into-a-serverless-application-and-deploy-it-to-aws-lambda-step-by-8ff6cc97780f
One thing you may be doing wrong (which is exactly what I did wrong but got a hint about from #Ramratan Gupta above) is to put the NAT gateway in the private subnet and not in the public.
The NAT gateway provides your private IP Lambda function with internet connectivity and so it sort of stands to reason the NAT gateway needs to have internet access itself and be in the Public network.
To summarise:
You have to create at least two subnets: one public and one private. Put both in the same VPC.
What makes a subnet public or private is the 0.0.0.0/0 route.
You need to have both an internet gateway (igw) and a NAT gateway (ngw).
To create the NAT gateway, you need an Elastic IP.
Also, and here's what I did wrong, you need to create the NAT gateway in the PUBLIC network.
The igw goes in the same subnet that the NAT gateway is: the public one.
You need to have two routes: one with the 0.0.0.0/0 route referencing the igw and the other referencing the ngw.
You then need to associate the NAT-route containing route table with the private subnet and the igw-route containing route table with the public subnet. Please note that until you do this association, there is no difference between the subnet that would make one public and one private. You make one private and the other public by how you associate the subnets with the route tables.
Finally, you need to connect your Lambda function to the VPC and also to the private subnet only. This way, when your lambda tries to reach the internet, it goes to the private subnet, looks for the 0.0.0.0/0 route, which directs it to the NAT gateway that is in the public subnet. The NAT gateway then contacts the internet using the igw (because they are in the same subnet) and upon receiving a response, returns it to your Lambda function.
Please also note that there are some permissions your Lambda function needs (that AWS will warn you about) in order to connect to a VPC.
Setting up AWS Lambda Internet access in VPC mode is tricky as no proper AWS documentation is provaded on AWS side, I did read this aritical many times https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/ but did not wached YouTube Video. After so much of R&D I can summrise as below steps are need for set up AWS Lambda in VPC mode
- Route Tables two router
- One for EC2 - EC2_ROUTER
- Another for AWS Lambda - AWS_Lambda_ROUTER
- Create an Internet Gateway
- Add 0.0.0.0/0 rule in EC2_ROUTER for target igw-xxxxx
- This will create public subnet and give INTERNET access for EC2
- Create a NATGateway with public subnet which has igw-xxxxx as target
- Create a private subnet which and attach to AWS_Lambda_ROUTER, with target 0.0.0.0/0 as nat-xxxxxxx
- Select VPC for AWS Lambda
- Select a/all private subnet which is private having NAT Gateway for all traffic 0.0.0.0/0
all done, go ahead and enjoy
Note
NATGateway is required when access to public API other than AWS
There is AWS Endpoints for internal AWS services, and one can attach AWS endpoints in AWS_Lambda_ROUTER by creating
Internet access in AWS Lambda -> Private Subnet with NATGateway -> NATGateway is in public subnet with Internet Gateway which access to AWS Lambda.
PS
I have no Idea why AWS Lambda can not have INTERNET access via InternetGateway why it needs NATGateway
i need to connect elastic cache and dynamo db from a single lambda function. My code is
exports.handler = (event, context, callback) => {
var redis = require("redis");
var client;
function connectRedisClient() {
client = redis.createClient(6379, "dgdfgdfgdfgdfgdfgfd.use1.cache.amazonaws.com", { no_ready_check: true });
}
connectRedisClient();
client.set('sampleKey', 'Hello World', redis.print);
console.log("set worked");
client.quit();
var AWS = require("aws-sdk");
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "dummy";
var year = 2015;
var title = "The Big New Movie";
var params = {
TableName: table,
Item: {
"userid": "manafcj",
"year": year,
"title": title,
"test1": [645645, 7988],
"info": {
"plot": "Nothing happens at all.",
"rating": 0
}
}
};
console.log("Adding a new item...");
docClient.put(params, function (err, data) {
if (err) {
console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Added item:", JSON.stringify(data, null, 2));
}
});
callback(null, 'Hello from Lambda');
};
I executed this lambda code without configuring vpc, elastic cache section is not working , but dynamo insertion is done perfectly.
after that i made setup for VPC in my account by following steps.
create vpc
name : test-vpc-name
CIDR block:172.31.0.0/16
Tenancy:Default
Create a new subnet.
name tag : test-subnet-1a
CIDR block :172.31.0.0/20
name tag : test-subnet-1b
CIDR block :172.31.16.0/20
Create a route table
name tag : test-route-table
Create a internet gateway
name:test-internet-gateway
Attach VPC
Route all outbound 0.0.0.0/0 traffic in routes
Create a route table subnet association
Create a NAT Gateway
subnet : test-subnet-1a
also i have configured my elastic cache setup by following steps
Create subnet cache group
name : test-cache-group
Create elastic cache
type: redis
Cluster Name : test-cache
subnet cache group : test-cache-group
Finally, i have configured newly created vpc on my lambda function. Then redis-elastic cache connection is working fine, but dynamo db connection is lost. I need both working fine from a single lambda function.
I think, some fault in VPC configuration with NAT Gateway.
What is the actual issue in this setup?
Lambda and DynamoDB are executed in the AWS Public Cloud. Both are services executed in a internet facing environment. The Elastic Cache Cluster, otherwise, is user managed service that runs on your own VPC.
The first option to give access to your elastic cache cluster to your lambda function is using a NAT instance to foward external network connections to Elastic Cache cluster inside your VPC. You can get use the instructions from this document to help you with this task.
The second option, is the one that you already tried. Amazon says that when you configure this option it does not means that the Lambda will be executed inside your VPC. What is does it define the Elastic Network Interface of the Lambda container to access your VPC. At the end of day I don't think that this makes difference. You can see the details here.
But the point is, the container where your lambda is executed has only one Elastic Network Interface. If you configure your lambda to use your VPC, the Network Interface will be configured to access your subnet using a private IP and lost the internet connection. So, it will not be able to access DynamoDB unless you have a configure NAT instance/Gateway in your VPC.
As per you told us. You configured your VPC with a NAT Gateway. If all were correctly configured, this should be working. Maybe you can try the fist option, leaving your lambda outside your VPC and configuring the NAT Gateway to route the inboud connections to your Elastic Cache Cluster.
Why don't try and tell us the result?
There is now a relatively easy solution: VPC Endpoints.
"Previously, if you wanted your EC2 (elroy: or lambda) instances in your VPC to be able to access DynamoDB, you had two options. You could use an Internet Gateway (with a NAT Gateway or assigning your instances public IPs) or you could route all of your traffic to your local infrastructure via VPN or AWS Direct Connect and then back to DynamoDB."
"A VPC endpoint for DynamoDB enables Amazon EC2 instances in your VPC to use their private IP addresses to access DynamoDB with no exposure to the public Internet...Your EC2 instances do not require public IP addresses, and you do not need an Internet gateway, a NAT device, or a virtual private gateway in your VPC. You use endpoint policies to control access to DynamoDB. Traffic between your VPC and the AWS service does not leave the Amazon network. "
The above quotes come from the links below. Note the the references to "EC2 instances" apply to lambda contexts as well.
See https://aws.amazon.com/blogs/aws/new-vpc-endpoints-for-dynamodb/
and
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/vpc-endpoints-dynamodb.html
Edited to provide more details in line.