I have an EC2 and lambda in the same VPC. The EC2 is running a web server, and I only want it accessible via my lambda (and ssh), so I set the EC2 security group to have inbound rule http-tcp-80-LambdaSecurityGroup (and ssh-tcp-22-MyHomeIP).
The LambdaSecurityGroup allows all outbound traffic (1 rule: AllTraffic-All-All-0.0.0.0/0). The lambda is in private subnets, and connects to the internet using a NAT gateway. Basically I setup lambda as described in Access Resources in a VPC from Your Lambda Functions, Giving Lambda functions access to resources in an Amazon VPC, and the first answer in Stack Overflow - AWS security group inbound rule.
When I (use AWS console's Test to) run my lambda, it does not connect to EC2 (times out after 10-11 seconds). But if I change the EC2 security group to allow inbound http-tcp-80-0.0.0.0/0 (Anywhere IPv4), then everything works as expected (EC2 web server receives lambda request and replies).
But of course I don't want to open up my EC2 web server to the entire public, so how can I get my EC2 to only allow the http (post) requests coming from my lambda?
Reasoning / Debugging:
Additional Details:
const postRequestData = { key1: value1, key2: value2 };
return new Promise((resolve, reject) => {
fetch('http://1.2.3.4/post:80', { // Note: uses EC2 public IPv4 address
method: 'post',
body: JSON.stringify(postRequestData),
headers: {'Content-Type': 'application/json'}
})
.then((response) => {
console.log("Response: ", response);
resolve(response);
})
.catch(err => {
console.log("ERROR: Could not fetch response: ", err);
reject("EC2 unavailable.");
});
});
The issue is actually with using the public EC2 IP, isn't it?
When you use the public IP, the Lambda function exits your VPC. So, within a VPC, it's generally more effective and secure to use the private IP for communication.