问题
After adding my Ruby Lambda function to a VPC and attaching the relevant SecurityGroups, I have problems retrieving the SSM credentials for pulling config from aws SSM Parameter Store and I bump into this weird network error after timeout.
This happens when trying to retrieve SSM credentials via ssm.get_parameters_by_path
but the trace feels like this would have happened on any other AWS call.
{
"errorMessage": "execution expired",
"errorType": "Function<Seahorse::Client::NetworkingError>",
"stackTrace": [
"/var/lang/lib/ruby/2.5.0/net/http.rb:937:in `initialize'",
"/var/lang/lib/ruby/2.5.0/net/http.rb:937:in `open'",
"/var/lang/lib/ruby/2.5.0/net/http.rb:937:in `block in connect'",
"/var/lang/lib/ruby/2.5.0/timeout.rb:103:in `timeout'",
"/var/lang/lib/ruby/2.5.0/net/http.rb:935:in `connect'",
"/var/lang/lib/ruby/2.5.0/net/http.rb:920:in `do_start'",
"/var/lang/lib/ruby/2.5.0/net/http.rb:915:in `start'",
"/var/lang/lib/ruby/2.5.0/delegate.rb:83:in `method_missing'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/net_http/connection_pool.rb:297:in `start_session'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/net_http/connection_pool.rb:96:in `session_for'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/net_http/handler.rb:121:in `session'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/net_http/handler.rb:73:in `transmit'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/net_http/handler.rb:47:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/plugins/content_length.rb:12:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/json/error_handler.rb:8:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/signature_v4.rb:66:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/helpful_socket_errors.rb:10:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:171:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:202:in `retry_request'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:185:in `retry_if_possible'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:173:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:202:in `retry_request'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:185:in `retry_if_possible'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:173:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:202:in `retry_request'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:185:in `retry_if_possible'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/retry_errors.rb:173:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/json/handler.rb:11:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/user_agent.rb:13:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/endpoint_pattern.rb:28:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/endpoint_discovery.rb:78:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/plugins/endpoint.rb:45:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/param_validator.rb:24:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/plugins/raise_response_errors.rb:14:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:20:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/idempotency_token.rb:17:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/param_converter.rb:24:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/aws-sdk-core/plugins/response_paging.rb:10:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/plugins/response_target.rb:23:in `call'",
"/var/runtime/gems/aws-sdk-core-3.40.0/lib/seahorse/client/request.rb:70:in `send_request'",
"/var/runtime/gems/aws-sdk-ssm-1.34.0/lib/aws-sdk-ssm/client.rb:4495:in `get_parameters_by_path'",
If I remove the function from the VPC everything runs fine. What went wrong ? (Note that I have added the VPC permission to my lambda role, as well as SSM access)
My SSM client is initialized this way
def ssm
@ssm ||= Aws::SSM::Client.new
end
回答1:
EDIT: I had misunderstood the OP's question, so I have edited accordingly trying to explain why it may be failing.
When your Lambda needs to access other AWS Services from within a VPC, your function will need access to your VPC AND to the Internet. This is achievable by attaching both public AND private subnets. The public subnet is the one which has an internet gateway attached to it and therefore can access the public internet and the private subnet is the one that is accessed through a NAT Gateway, visible only inside the AWS VPC.
Also, keep in mind that your Security Groups must allow inbound TCP connections from 0.0.0.0/0 (or just whitelist the host you want to allow).
If you can, avoid putting your Lambda Function inside a VPC as much as you can, since it can increase the cold starts significantly (sometimes it adds 10 seconds on top of your request, which will cause most of your Lambda functions to timeout if not configured properly)
Hope this helps!
EDIT 2: I will try to walk you through the process of creating a new VPC through the wizard with two subnets (public and private), allowing the inbound rules on the SG and finally attaching the SNs and the SG to the Lambda function
Please create an Elastic IP beforehand
Through the console, click on VPC, then click on Launch VPC Wizard
Select VPC with Public and Private Subnets
Leave the default config and add the Elastic IP you've just created
Once your VPC is created, you should now have a public and a private subnet
By default, your SG will already be accepting All Traffic
Finally, go to your Lambda function and, under the VPC section, add your Subnets and the Security Group.
And voilá, your Lambda should now be able to access the Internet (or other AWS Services)
来源:https://stackoverflow.com/questions/54815711/aws-lambda-ruby-on-vpc-seahorseclientnetworkingerror