AWS Lambda cannot connect to AWS services in VPC - amazon-web-services

I've a lambda in VPC to access Amazon DocDB, but failed to access any resource in VPC. I've read the official guide for days still didn't fix this issue.
I checked all vpc configurations according to Official Guide but got no luck.
VPC is assigned when creating lambda.
Could anyone give me some help on the lambda configurations ? :)
def access_mongodb(event, context):
url = event.get('url')
if url:
db = event.get('db')
coll = event.get('collection')
query = event.get('query')
limit = int(event.get('limit'))
try:
with Mongo(url=url, db=db) as conn:
logger.info('Lambda Start query with Mongo')
for row in conn[coll].find(query).limit(limit):
logger.info(f'got row => {json.dumps(row, default=str)}')
except Exception as e:
logger.error(f'Got exception {e}')
else:
logger.info('Lambda End with out Mongo')
Errors:
Got exception No servers found yet, Timeout: 2.0s, Topology Description: <TopologyDescription id: 62b5186720247fb7d69a0765, topology_type: Single, servers: [<ServerDescription ('docdb-test.xxxx-southeast-1.docdb.amazonaws.com', 27017) server_type: Unknown, rtt: None>]>
Configurations:
aws lambda get-function-configuration --function-name hello_py3
{
"FunctionName": "hello_py3",
"FunctionArn": "arn:aws:lambda:ap-southeast-1:592017647781:function:hello_py3",
"Runtime": "python3.9",
"Role": "arn:aws:iam::592017647781:role/service-role/hello_py3-role-xh39m23g",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 5701329,
"Description": "",
"Timeout": 10,
"MemorySize": 128,
"LastModified": "2022-06-24T01:26:48.000+0000",
"CodeSha256": "VLwda8fP2DM62/y4Ouy9/U3KpzvfSRWoH7ocCwl1G6g=",
"Version": "$LATEST",
"VpcConfig": {
"SubnetIds": [
"subnet-08dacd9b6970624aa",
"subnet-09f80e8227735f6cf",
"subnet-028392620db2f9753"
],
"SecurityGroupIds": [
"sg-0002ee69773ca6f9d"
],
"VpcId": "vpc-0eee2636f691ad96b"
},
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "55af10eb-f777-4ba9-aea5-05a010ce7637",
"State": "Active",
"LastUpdateStatus": "Successful",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
}
}
aws iam list-attached-role-policies --role-name hello_py3-role-xh39m23g
{
"AttachedPolicies": [
{
"PolicyName": "AWSLambdaVPCAccessExecutionRole-2400d95b-c83c-4fce-8e12-b1a8c5c4b503",
"PolicyArn": "arn:aws:iam::592017647781:policy/service-role/AWSLambdaVPCAccessExecutionRole-2400d95b-c83c-4fce-8e12-b1a8c5c4b503"
},
{
"PolicyName": "AWSLambdaBasicExecutionRole-a8dac45b-b9f1-4eab-8170-2c9b9f9358ce",
"PolicyArn": "arn:aws:iam::592017647781:policy/service-role/AWSLambdaBasicExecutionRole-a8dac45b-b9f1-4eab-8170-2c9b9f9358ce"
}
]
}
aws ec2 describe-vpcs --vpc-ids vpc-0eee2636f691ad96b
{
"Vpcs": [
{
"CidrBlock": "172.31.0.0/16",
"DhcpOptionsId": "dopt-0b9edd5b6deafa0db",
"State": "available",
"VpcId": "vpc-0eee2636f691ad96b",
"OwnerId": "592017647781",
"InstanceTenancy": "default",
"CidrBlockAssociationSet": [
{
"AssociationId": "vpc-cidr-assoc-0200675b36f061104",
"CidrBlock": "172.31.0.0/16",
"CidrBlockState": {
"State": "associated"
}
}
],
"IsDefault": true
}
]
}
aws ec2 describe-security-groups --group-ids sg-0002ee69773ca6f9d
{
"SecurityGroups": [
{
"Description": "default VPC security group",
"GroupName": "default",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"ToPort": 80,
"UserIdGroupPairs": []
},
{
"IpProtocol": "-1",
"IpRanges": [],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": [
{
"GroupId": "sg-0047473f289f0ffd3",
"UserId": "592017647781"
},
{
"GroupId": "sg-031e0901b061eb92d",
"UserId": "592017647781"
},
{
"GroupId": "sg-03f39f48c7887e46b",
"UserId": "592017647781"
},
{
"GroupId": "sg-07d8dbe45e3e81e44",
"UserId": "592017647781"
}
]
}
],
"OwnerId": "592017647781",
"GroupId": "sg-0002ee69773ca6f9d",
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"VpcId": "vpc-0eee2636f691ad96b"
}
]
}
UPDATE:
I finally figure it out by applying ReachabilityAnalyzer, and it was proved to be my fault on confusing configuration items. This is a very helpful tool, guys have same issue can try to use this tool to help themselves out.
Thanks John for help.

You appear to be using a single Security Group for both the AWS Lambda function and the DocDB database. I think your Security Group is missing Outbound permissions, which be restricting traffic from the Lambda function.
The typical security setup would be:
A security group on the AWS Lambda function (Lambda-SG) that permits all Outbound access
A security group on the DocDB (DB-SG) that permits Inbound access from Lambda-SG on port 27017

Could you please check the connection from the lambda subnet to documentdb subnet and there sg & nacl just to confirm that lambda can connect to the documentdb using port 27017.
Thanks,
Chinmoy Layek

Related

AWS Certificate Manager Pending Validation when DNS validation is successful

Resolved! - Ended up just needing to contact Amazon Support to push it through.
I'm attempting to renew a certificate created in AWS Certificate Manager (ACM), but I'm stuck in the dreadful PENDING_VALIDATION status; this is a DNS validated certificate where I validated using the CNAME record.
Under domains I can see the domain validation has a status of Success and Renewal Status of Success
If I run aws acm describe-certificate --certificate-arn "examplearn", I get a return showing DomainValidationOptions with the ValidationStatus being success for the CNAME validation.
Replaced with "example" for sensitive values
{
"Certificate": {
"CertificateArn": "arn:aws:acm:us-east-1:example:certificate/certid",
"DomainName": "*.example.com",
"SubjectAlternativeNames": [
"*.example.com"
],
"DomainValidationOptions": [
{
"DomainName": "*.example.com",
"ValidationDomain": "*.example.com",
"ValidationStatus": "SUCCESS",
"ResourceRecord": {
"Name": "examplename",
"Type": "CNAME",
"Value": "examplevalue"
},
"ValidationMethod": "DNS"
}
],
"Serial": "",
"Subject": "CN=*.example.com",
"Issuer": "Amazon",
"CreatedAt": "2019-01-17T12:53:01-08:00",
"IssuedAt": "2021-10-22T21:21:50.177000-07:00",
"Status": "ISSUED",
"NotBefore": "2021-10-22T17:00:00-07:00",
"NotAfter": "2022-11-23T15:59:59-08:00",
"KeyAlgorithm": "RSA-2048",
"SignatureAlgorithm": "SHA256WITHRSA",
"InUseBy": [
"example",
"example",
"example",
"example"
],
"Type": "AMAZON_ISSUED",
"RenewalSummary": {
"RenewalStatus": "PENDING_VALIDATION",
"DomainValidationOptions": [
{
"DomainName": "*.example.com",
"ValidationDomain": "*.example.com",
"ValidationStatus": "SUCCESS",
"ResourceRecord": {
"Name": "examplename",
"Type": "CNAME",
"Value": "examplevalue"
},
"ValidationMethod": "DNS"
}
],
"UpdatedAt": "2022-09-21T23:39:15.161000-07:00"
},
"KeyUsages": [
{
"Name": "DIGITAL_SIGNATURE"
},
{
"Name": "KEY_ENCIPHERMENT"
}
],
"ExtendedKeyUsages": [
{
"Name": "TLS_WEB_SERVER_AUTHENTICATION",
"OID": "1.3.6.1.5.5.7.3.1"
},
{
"Name": "TLS_WEB_CLIENT_AUTHENTICATION",
"OID": "1.3.6.1.5.5.7.3.2"
}
],
"RenewalEligibility": "ELIGIBLE",
"Options": {
"CertificateTransparencyLoggingPreference": "ENABLED"
}
}
}
Followed instructions successfully in https://aws.amazon.com/premiumsupport/knowledge-center/acm-certificate-pending-validation/ (checking cname response exactly matches what is in acm CNAME values when copy pasting)
The site domain registration is in Route 53 with NS pointing to cloudflare, where DNS is managed.
Is there something obvious that pops out to you? Thank you!

10060 error when connecting MariaDB on VM on Compute Engine of Google Cloud Platform

Created a VM on Compute Engine of Google Cloud Platform.
Installed Maria DB. Configured binding to 0.0.0.0.
Created a firewall rule to allow access to 3306 in the IP ranged 0.0.0.0/0. Tagged it as "mysql-open" and Added it as a network tag in the VM instance detail. I also chose the option to log the connection.
When I try to connect from MySQL workbench to the public address of the VM Instance with 3306 as the Port, I get a
10060 error.
The user ID used to connect was given full GRANT and was like 'testuser'#'%'.
Below is the log entry. Which seems to show that the firewall rule worked.
"insertId": "epk9z8g1zjxknf",
"jsonPayload": {
"instance": {
"project_id": "XXXX",
"vm_name": "XXX",
"region": "us-east4",
"zone": "us-east4-c"
},
"connection": {
"src_port": 44826,
"dest_ip": "10.150.0.5",
"protocol": 6,
"dest_port": 3306,
"src_ip": "198.199.98.246"
},
"remote_location": {
"city": "San Francisco",
"continent": "America",
"country": "usa",
"region": "California"
},
"rule_details": {
"priority": 2000,
"ip_port_info": [
{
"port_range": [
"3306"
],
"ip_protocol": "TCP"
}
],
"source_range": [
"0.0.0.0/0"
],
"reference": "network:default/firewall:mysql-open",
"action": "ALLOW",
"direction": "INGRESS"
},
"vpc": {
"project_id": "XXXX",
"vpc_name": "default",
"subnetwork_name": "default"
},
"disposition": "ALLOWED"
},
"resource": {
"type": "gce_subnetwork",
"labels": {
"subnetwork_id": "2510359252254555075",
"project_id": "XXXX",
"subnetwork_name": "default",
"location": "us-east4-c"
}
},
"timestamp": "2020-11-05T14:12:33.819891417Z",
"logName": "projects/XXXX/logs/compute.googleapis.com%2Ffirewall",
"receiveTimestamp": "2020-11-05T14:12:39.166067521Z"
}

Why can't I connect to a new AWS Aurora Serverless instance from my PC?

Trying to set up a vanilla AWS RDS Aurora Serverless instance.
For now, I just want to connect to it directly from my PC as a sanity check, but I'm unable to do so. Every time I connect via $ mysql, it hands for a few minutes. Then I get:
$ mysql -h <MY-DATABASE>.cluster-deadbeef.us-west-1.rds.amazonaws.com -P 3306 -u admin -p
ERROR 2003 (HY000): Can't connect to MySQL server on '<MY-DATABASE>.cluster-deadbeef.us-west-1.rds.amazonaws.com' (60)
(nc also just times out)
Looks like there's a network connectivity I've made somewhere, but I'm not sure where.
Here's the entire setup (think I've included everything relevant?):
Database Instance:
$ aws rds describe-db-clusters --output json | jq '.DBClusters[0] | {AvailabilityZones, DBSubnetGroup, VpcSecurityGroups}'
{
"AvailabilityZones": [
"us-west-1c",
"us-west-1b"
],
"DBSubnetGroup": "default-vpc-0165fd69fae5d2569",
"VpcSecurityGroups": [
{
"VpcSecurityGroupId": "sg-051e6ad0fe8837a56",
"Status": "active"
}
]
}
VPC:
$ aws ec2 describe-vpcs --output json | jq '.Vpcs[0] | {VpcId, CidrBlock, CidrBlockAssociationSet}'
{
"VpcId": "vpc-0165fd69fae5d2569",
"CidrBlock": "10.0.0.0/16",
"CidrBlockAssociationSet": [
{
"AssociationId": "vpc-cidr-assoc-0fe35851049a94f32",
"CidrBlock": "10.0.0.0/16",
"CidrBlockState": {
"State": "associated"
}
}
]
}
VPC Subnets:
$ aws ec2 describe-subnets --output json | jq '.Subnets[] | {AvailabilityZone,AvailabilityZoneId,CidrBlock,VpcId}'
{
"AvailabilityZone": "us-west-1c",
"AvailabilityZoneId": "usw1-az1",
"CidrBlock": "10.0.1.0/24",
"VpcId": "vpc-0165fd69fae5d2569"
}
{
"AvailabilityZone": "us-west-1b",
"AvailabilityZoneId": "usw1-az3",
"CidrBlock": "10.0.0.0/24",
"VpcId": "vpc-0165fd69fae5d2569"
}
Security Group:
Yes this is totally wide open for now, still can't connect :(
$ aws ec2 describe-security-groups --output json | jq '.SecurityGroups[]'
{
"IpPermissions": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [
{
"CidrIpv6": "::/0"
}
],
"PrefixListIds": [],
"UserIdGroupPairs": [
{
"GroupId": "sg-051e6ad0fe8837a56",
}
]
},
{
"FromPort": 3306,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [
{
"CidrIpv6": "::/0"
}
],
"PrefixListIds": [],
"ToPort": 3306,
"UserIdGroupPairs": []
}
],
"GroupId": "sg-051e6ad0fe8837a56",
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"VpcId": "vpc-0165fd69fae5d2569"
}
Route Table:
$ aws ec2 describe-route-tables --output json | jq '.RouteTables[]'
{
"Associations": [
{
"Main": true,
"RouteTableAssociationId": "rtbassoc-0aebc4a882b0cd2a5",
"RouteTableId": "rtb-0ce6ee26652736941",
"AssociationState": {
"State": "associated"
}
},
{
"Main": false,
"RouteTableAssociationId": "rtbassoc-047d54469da606a50",
"RouteTableId": "rtb-0ce6ee26652736941",
"SubnetId": "subnet-0744475e288c0424c",
"AssociationState": {
"State": "associated"
}
},
{
"Main": false,
"RouteTableAssociationId": "rtbassoc-08c5ea54642014c95",
"RouteTableId": "rtb-0ce6ee26652736941",
"SubnetId": "subnet-0b9c99ff38b860725",
"AssociationState": {
"State": "associated"
}
}
],
"RouteTableId": "rtb-0ce6ee26652736941",
"Routes": [
{
"DestinationCidrBlock": "10.0.0.0/16",
"GatewayId": "local",
"Origin": "CreateRouteTable",
"State": "active"
},
{
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": "igw-0f8ad7dfe1eaa0c67",
"Origin": "CreateRoute",
"State": "active"
}
],
"VpcId": "vpc-0165fd69fae5d2569",
}
What am I missing?
thanks!!
For now, I just want to connect to it directly from my PC
You can not access serverless-DB from your local system, it is only accessible with-in AWS network.
You can configure ssh-tunnel through your EC2 instance to access serverless DB or use VPN that is running in the same VPC.
Because Aurora Serverless DB clusters do not have publically accessible endpoints, your MyClusterName can only be accessed from within the same VPC.
configure-connect-serverless-mysql-database-aurora

"NLB ARN is malformed" when create VPC link for AWS APIGateway

I followed the tutorial to create a VPC link to my private elb balancer.
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-api-with-vpclink-cli.html
But it failed, and got an error message "statusMessage": "NLB ARN is malformed".
I do find the ELB with same ARN by elbv2 cli, so the ARN must be a legal one...
I can't find document to solve the problem.
anyone can help me? thank you.
what i did is as following.
$ aws elbv2 describe-load-balancers --load-balancer-arns arn:aws:elasticloadbalancing:ap-northeast-1:846239845603:loadbalancer/app/v2-api-balancer/db49ab0ecaef1de8
{
"LoadBalancers": [
{
"Scheme": "internal",
"SecurityGroups": [
"sg-9282b8f4"
],
"LoadBalancerArn": "arn:aws:elasticloadbalancing:ap-northeast-1:846239845603:loadbalancer/app/v2-api-balancer/db49ab0ecaef1de8",
"State": {
"Code": "active"
},
"CreatedTime": "2017-10-18T04:27:28.780Z",
"VpcId": "vpc-dbe3f2be",
"DNSName": "internal-v2-api-balancer-988454399.ap-northeast-1.elb.amazonaws.com",
"AvailabilityZones": [
{
"SubnetId": "subnet-7642062e",
"ZoneName": "ap-northeast-1c"
},
{
"SubnetId": "subnet-c454fa8d",
"ZoneName": "ap-northeast-1b"
}
],
"IpAddressType": "ipv4",
"Type": "application",
"LoadBalancerName": "v2-api-balancer",
"CanonicalHostedZoneId": "Z14GRHDCWA56QT"
}
]
}
$ aws apigateway create-vpc-link \
--name my-test-vpc-link-1 \
--target-arns "arn:aws:elasticloadbalancing:ap-northeast-1:846239845603:loadbalancer/app/v2-api-balancer/db49ab0ecaef1de8"
{
"name": "my-test-vpc-link-1",
"targetArns": [
"arn:aws:elasticloadbalancing:ap-northeast-1:846239845603:loadbalancer/app/v2-api-balancer/db49ab0ecaef1de8"
],
"id": "7eexgn",
"status": "PENDING"
}
$ aws apigateway get-vpc-link --vpc-link-id 7eexgn
{
"id": "7eexgn",
"targetArns": [
"arn:aws:elasticloadbalancing:ap-northeast-1:846239845603:loadbalancer/app/v2-api-balancer/db49ab0ecaef1de8"
],
"status": "FAILED",
"name": "my-test-vpc-link-1",
"statusMessage": "NLB ARN is malformed"
}
VPC Links must be to a network LB. Looks like you are trying to use an application LB.
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-nlb-for-vpclink-using-console.html

JMES Path / AWS - Retrieve Load Balancer name for given instance ID

I need to find the load balancer that a given EC2 instance is attached to using the AWS CLI. I have a working solution that uses jq, however I would like to avoid installing jq as a dependency and write the query in JMESPath if possible. I am stuck on the query format of the JMESPath expression.
I found this question: Filter LoadBalancer By VPC ID, which is exactly what I'm trying to do except filter by instance ID, instead of VPC ID . I think the problem is that the instance ids are in an array.
Working solution with jq:
aws elb describe-load-balancers | jq -r '.LoadBalancerDescriptions[] | select(.Instances[].InstanceId == "i-12345678") | .LoadBalancerName
What I'm trying with JMESPath:
aws elb describe-load-balancers --query "LoadBalancerDescriptions[?Instances[].InstanceId=='i-12345678'] | [].LoadBalancerName"
I feel like I am very close but missing something fundamental.
Example JSON ouput of the describe-load-balancers command from AWS documentation:
{
"LoadBalancerDescriptions": [
{
"Subnets": [
"subnet-15aaab61"
],
"CanonicalHostedZoneNameID": "Z3DZXE0EXAMPLE",
"CanonicalHostedZoneName": "my-load-balancer-1234567890.us-west-2.elb.amazonaws.com",
"ListenerDescriptions": [
{
"Listener": {
"InstancePort": 80,
"LoadBalancerPort": 80,
"Protocol": "HTTP",
"InstanceProtocol": "HTTP"
},
"PolicyNames": []
},
{
"Listener": {
"InstancePort": 443,
"SSLCertificateId": "arn:aws:iam::123456789012:server-certificate/my-server-cert",
"LoadBalancerPort": 443,
"Protocol": "HTTPS",
"InstanceProtocol": "HTTPS"
},
"PolicyNames": [
"ELBSecurityPolicy-2015-03"
]
}
],
"HealthCheck": {
"HealthyThreshold": 2,
"Interval": 30,
"Target": "HTTP:80/png",
"Timeout": 3,
"UnhealthyThreshold": 2
},
"VPCId": "vpc-a01106c2",
"BackendServerDescriptions": [
{
"InstancePort": 80,
"PolicyNames": [
"my-ProxyProtocol-policy"
]
}
],
"Instances": [
{
"InstanceId": "i-207d9717"
},
{
"InstanceId": "i-afefb49b"
}
],
"DNSName": "my-load-balancer-1234567890.us-west-2.elb.amazonaws.com",
"SecurityGroups": [
"sg-a61988c3"
],
"Policies": {
"LBCookieStickinessPolicies": [
{
"PolicyName": "my-duration-cookie-policy",
"CookieExpirationPeriod": 60
}
],
"AppCookieStickinessPolicies": [],
"OtherPolicies": [
"my-PublicKey-policy",
"my-authentication-policy",
"my-SSLNegotiation-policy",
"my-ProxyProtocol-policy",
"ELBSecurityPolicy-2015-03"
]
},
"LoadBalancerName": "my-load-balancer",
"CreatedTime": "2015-03-19T03:24:02.650Z",
"AvailabilityZones": [
"us-west-2a"
],
"Scheme": "internet-facing",
"SourceSecurityGroup": {
"OwnerAlias": "123456789012",
"GroupName": "my-elb-sg"
}
}
]
}
aws elb describe-load-balancers --query LoadBalancerDescriptions[?Instances[0].InstanceId==`i-55555555`].LoadBalancerName
Since Instances is an array, you should make use of the contains function to search for your instance id.
aws elb describe-load-balancers --query LoadBalancerDescriptions[?contains(Instances[*].InstanceId,`i-12345678`)].LoadBalancerName
Use LoadBalancerDescriptions[?Instances[*].InstanceId==`i-55555555`] to iterate through the instances.
LoadBalancerDescriptions[?Instances[0].InstanceId==`i-55555555`] will only use the first element in the array.