С февраля месяца 2016 года сервис AWS Lambda получил возможность доступа к ресурсам внутри Virtual Private Cloud, но по умолчанию все лямбды работают вне VPC. Поскольку эта возможность появилась относительно недавно и статей, как это реализовать, не так много, мы хотели бы поделиться с вами своим опытом.
Мы разработали мобильное приложение, построенное на AWS. Сервис Lambda отлично подошел для написания небольшой серверной логики, к тому же легко масштабируемой.
Задача лямбде была поставлена довольно тривиальная: выполнять запрос к DynamoDB и самые популярные запросы кэшировать, используя Elasticache. Проблема, с которой мы столкнулись, связана с настройкой доступа из VPC к внутренним и внешним ресурсам Amazon.
В нашем случае было необходимо обеспечить доступность сервиса Elasticache (в VPC) и DynamoDB (вне 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). Пример:
Давайте проверим как это всё у нас полетит. В настройках лямбды выбираем 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"
И после запуска увидим заветный результат:
Вывод
Работа с сервисами Amazon вне и внутри VPC открывает много возможностей использования AWS Lambda. Представленную в этой статье схему настроек для VPC можно использовать как универсальное решение, для обеспечения доступа к любым другим сервисам внутри и вне VPC.
Полезные ссылки:
Lambda in VPC
Your VPC and Subnets
Getting Started with Amazon ElastiCache
Автор: SimbirSoft