title: AWS Lambda access Secrets Manager from within VPC
body: <p>I have a lambda that needs to communicate 'locally' with an EC2 instance in a private VPC.
  The API key is being stored in Secrets Manager.</p>
  <p>Using the default code provided by Secrets Manager and the necessary IAM roles I am able to read the API key from Secrets Manager in my Lambda:</p>
  <pre class="lang-py prettyprint-override"><code># Use this code snippet in your app.
  # If you need more information about configurations or implementing the sample code, visit the AWS docs:   
  # https://aws.amazon.com/developers/getting-started/python/
  
  import boto3
  import base64
  from botocore.exceptions import ClientError
  
  def get_secret():
  
      secret_name = &quot;MYSECRET&quot;
      region_name = &quot;ap-southeast-2&quot;
  
      # Create a Secrets Manager client
      session = boto3.session.Session()
      client = session.client(
          service_name='secretsmanager',
          region_name=region_name
      )
  
      # In this sample we only handle the specific exceptions for the 'GetSecretValue' API.
      # See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
      # We rethrow the exception by default.
  
      try:
          get_secret_value_response = client.get_secret_value(
              SecretId=secret_name
          )
      except ClientError as e:
   ... # Default error handling..
      else:
          # Decrypts secret using the associated KMS CMK.
          # Depending on whether the secret is a string or binary, one of these fields will be populated.
          if 'SecretString' in get_secret_value_response:
              secret = get_secret_value_response['SecretString']
              return secret
          else:
              decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
              return decoded_binary_secret
   
  def lambda_handler(event, context):
      secrt = get_secret()
  
      return {
          'statusCode': 200,
          &quot;headers&quot;: {
              'Access-Control-Allow-Origin': '*',
              'Content-Type': 'application/json'
          },
          'body': secrt 
      }             
  </code></pre>
  <p>This Lambda is able to successfully retrieve and print the API key from Secrets Manager.</p>
  <p>To communicate with the EC2 instance I have a Lambda with a helper layer and some simple test code:</p>
  <pre class="lang-py prettyprint-override"><code>import apihelper
  import json
  
  def lambda_handler(event, context):
    conn = apihelper.getConnection('API KEY')
    return {
      'statusCode': 200,
      &quot;headers&quot;: {
        &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;
      },
      'body': json.dumps(conn.listProducts())
    }
  </code></pre>
  <p>This lambda is in the VPC, subnet and has the necessary security group rules to communicate with the EC2 instance. Hard coding the <code>API KEY</code> it successfully returns the expected data from the EC2 instance.</p>
  <p>When I try to combine them so that the API key is not hard-coded the Lambda no longer works. There is no error message it just times out.</p>
  <p>I have tried:</p>
  <ul>
  <li>Increasing the timeout to over a minute</li>
  <li>Placing <code>allow all</code> inbound and outbound rules on the security group</li>
  <li>Configuring a VPC endpoint for Secrets Manager</li>
  </ul>
  <p>I think I have narrowed it down to the VPC. The first Lambda that just prints out the secret works perfectly until I place it in the VPC. But I don't know where to look or how to configure it to allow the Lambda to talk to both the EC2 inside the VPC as well as Secrets Manager.</p>