С февраля месяца 2016 года сервис AWS Lambda получил возможность доступа к ресурсам внутри Virtual Private Cloud, но по умолчанию все лямбды работают вне VPC. Поскольку эта возможность появилась относительно недавно и статей, как это реализовать, не так много, мы хотели бы поделиться с вами своим опытом.

Мы разработали мобильное приложение, построенное на AWS. Сервис Lambda отлично подошел для написания небольшой серверной логики, к тому же легко масштабируемой.

Задача лямбде была поставлена довольно тривиальная: выполнять запрос к DynamoDB и самые популярные запросы кэшировать, используя Elasticache. Проблема, с которой мы столкнулись, связана с настройкой доступа из VPC к внутренним и внешним ресурсам Amazon.

В нашем случае было необходимо обеспечить доступность сервиса Elasticache (в VPC) и DynamoDB (вне VPC). Для достижения этой цели в VPC была развернута структура, которая представлена на схеме:

Структурная схема VPC


Далее приводится инструкция, как из AWS Console создать такую схему работы VPC.

Настройка VPC
Для начала необходимо создать VPC, если еще этого не сделали. Создать две подсети (Subnets) публичную и приватную.

Вторым шагом будет создание таблиц маршрутизации (Route Tables). По умолчанию у вас уже создана одна main таблица, она будет выполнять роль приватной таблицы. Остается только создать публичную таблицу. При создании необходимо указать наш VPC.

Для каждой каждой подсети (публичной и приватной) выберите соответствующую ей таблицу маршрутизации.

Далее создаем шлюз (internet gateway), который обеспечит доступ ко всем сервисам вне VPC и к внешним адресам в целом. После аттачим созданный шлюз к нашему VPC. Также создаем NAT-шлюз, который прикрепляем к публичной подсети.

И после всего остается только настроить таблицы маршрутизации:

  • Создаем маршрут в публичной таблице для созданного интернет шлюза. Пример:

Публичная таблица маршрутизации


  • Создаем маршрут в приватной таблице для NAT. Пример:

Приватная таблица маршрутизации


Настройка Elasticache

В нашем примере рассмотрим подключение Elasticache к приватной подсети. Для этого в панели Elasticache создадим группу для приватной подсети (Cache Subnet Group). И далее при создании кластера указываем созданную группу.

После всего остается только в панели VPC найти группу в Security Groups для нашей VPC (она создается автоматически) и добавить правило для порта нашего кластера (redis по умолчанию — 6379; memcached — 11211). Пример:

Правила для security group


Давайте проверим как это всё у нас полетит. В настройках лямбды выбираем VPC и приватную сеть. Запускаем код:

from __future__ import print_function
import json
import boto3
import decimal
import logging
import elasticache_auto_discovery
from pymemcache.client.hash import HashClient

CACHE_ENDPOINTS = 'exaplecache.wjbxgg.cfg.euw1.cache.amazonaws.com:11211'


def decimal_default(obj):
   if isinstance(obj, decimal.Decimal):
       return float(obj)
   raise TypeError


def lambda_handler(event, context):
   nodes_endpoints = elasticache_auto_discovery.discover(CACHE_ENDPOINTS)
   nodes = map(lambda x: (x[1], int(x[2])), nodes_endpoints)
   memcache_client = HashClient(nodes, timeout=60, connect_timeout=2)

   table = boto3.resource('dynamodb').Table('Photo')
   response = table.scan(Limit=20)
   memcache_client.set('example', json.dumps(response['Items'], default=decimal_default))

   cache_elements = memcache_client.get('example')

   if json.loads(cache_elements) == response['Items']:
       return "It works!"
   else:
       return "Doesn't work"


И после запуска увидим заветный результат:
image

Вывод
Работа с сервисами Amazon вне и внутри VPC открывает много возможностей использования AWS Lambda. Представленную в этой статье схему настроек для VPC можно использовать как универсальное решение, для обеспечения доступа к любым другим сервисам внутри и вне VPC.

Полезные ссылки:
Lambda in VPC
Your VPC and Subnets
Getting Started with Amazon ElastiCache
Поделиться с друзьями
-->

Комментарии (4)


  1. pragmader
    20.07.2016 16:43

    Здесь еще есть tutorial как можно попробовать AWS Lambda в несколько шагов с использованием шаблона. Недавно был workshop в офисе Amazon как раз на эту тему.


  1. random1st
    20.07.2016 17:16

    Схема для ElastiCache рабочая, однако можно поступить и наоборот — пробросить ElastiCache наружу. Для этого на любом инстансе включаем проброс командой

    sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination <IP кластера>:6379
    и получаем тот же эффект. Естественно, в securitygroup инстанса надо настроить доступ на порт.
    А вообще в целом у Амазона не так уж много сервисов, не имеющих внешнего эндпойнта, и навскидку оказалось проще наплевать на возможность использования лямбдой VPC, чем ковыряться с пробросом портов.


  1. 0vvland
    20.07.2016 17:32

    Будет лучше когда добавят Endpoints для Dynamo и пр в VPC, ка уже сделано для S3. Тогда отпадет надобность в NAT.


  1. ArtemA
    22.07.2016 23:38

    Стоит отметить, что NAT Gateway стоит $0.04 в час, что немало, особенно если держать его во всех трех AZ. Намного дешевле создать EC2 инстансы в VPC с Twemproxy для доступа к ElastiCache.