A/B -тестирование, синие/зеленые развертывания, канарейские релизы. Разные, но все же так много общего. Все они имеют разные цели, но используют в основном одно и то же техническое решение под капотом. Мы делаем такие испытания по нескольким причинам. Один — сделать тест A/B и определить, какую версию наших пользователей нравится лучшие. Уверен, что можно сделать A/B тестирование на клиентской стороне, но лично мне упростить на стороне сервера. Голубые/зеленые и канаречные развертывания сделаны, чтобы убедиться, что новая версия приложений работает так, как мы ожидаем и дам нам простой способ откатываться в предыдущую версию в случае проблемы. Все это важные практики в культуре DevOps.
Многие услуги от AWS предлагают это решение из коробки, одна услуга, которая не является Humentfront. К счастью, Cloudfront имеет возможность запустить лямбда @ kems, которую мы можем использовать для этого.
Весь исходный код для этой настройки найден на GitHub
Представляем Lambda @ Edge
Lambda может работать в четырех разных местах в потоке запросов.
Просмотр просмотра — работает, когда CloudFront получает запрос от зрителя. Происхождение запроса — бежит до того, как Cloudfront пересылает запрос к началу. Ответ происхождения — запускается, когда CloudFront получает ответ от начала координат. Ответ просмотра — запускается до того, как CloudFront возвращает ответ зрителям.
Есть несколько ограничений, когда дело доходит до лямбда@Edge, можно только создавать функции в Python и Node.js. Функции запроса просмотра и ответа могут выделять только 128 МБ памяти и работать только в течение 3 секунд. Вы не можете использовать переменные среды, вы не можете использовать Последние Версия псевдоним, поддерживаются только фиксированные версии. Журналы публикуются в области края, к которой вы получаете доступ, а не в US-EAST-1 регион, даже если функции должны быть развернуты в этом регионе. Обязательно прочитайте Документация Прежде чем начать работать с лямбда @ жрать.
Обзор решения
В этом решении мы собираемся использовать две разные функции Lambda для просмотр просмотра и Ответ происхождения Крюки, мы будем хранить конфигурацию в хранилище параметров, а S3 — наше происхождение.
В просмотр просмотра Крюк Мы проверим специальное cookie, если файл cookie не установлен, мы принесем случайную версию. В Ответ происхождения Мы устанавливаем Set-Cookie Заголовок для хранения версии, которую мы используем. Установив различные значения в хранилище параметров, мы можем управлять весом каждой версии, а также мы можем сбросить и заставить клиентов получать новую случайную версию.
Запрос на зритель
Начнем с функции Lambda, которая будет реагировать на событие запроса зрителя. Эта функция Lambda отвечает за проверку нашего cookie X-версия-имя Если значение установлено, функция обновит путь запроса на основе значения cookie. Если нет установленного значения, он будет катиться в Dice и получить случайную версию и обновить путь запроса. Эта функция также сопоставит значение в cookie X-версию-сброс к значению в магазине параметра, и если значение отличается, он будет игнорировать любое заданное значение в X-версия-имя Анкет Если нет значения в X-версия-имя Или если значение игнорируется, функция бросает кости и выбирает версию наугад. Вес для разных версий контролируется значением в магазине параметра. Наконец, функция передает файл cookie к следующему шагу в цепочке вызовов.
Код запроса просмотра
Полная версия доступна в GitHub Анкет
def lambda_handler(event, context): request = event['Records'][0]['cf']['request'] headers = request['headers'] cookie_version_blue = 'X-Version-Name=Blue' cookie_version_green = 'X-Version-Name=Green' path_blue = '/Blue' path_green = '/Green' uri = '' if request['uri'].endswith('/'): request['uri'] = request['uri'] + 'index.html' if 'cookie' not in request['headers']: request['headers']['cookie'] = [] # Reset weights, ignore already set cookie reset_weight, reset_cookie = do_weight_reset(headers) if not reset_weight: for cookie in headers.get('cookie', []): if cookie_version_blue in cookie['value']: uri = path_blue + request['uri'] break elif cookie_version_green in cookie['value']: uri = path_green + request['uri'] break request['headers']['cookie'].append( {'key': 'Cookie', 'value': reset_cookie}) if not uri: weight = int(load_parameter('Weight')) cookie_value = '' if random.random() < float(weight / 100.0): uri = path_blue + request['uri'] cookie_value = cookie_version_blue else: uri = path_green + request['uri'] cookie_value = cookie_version_green request['headers']['cookie'].append( {'key': 'Cookie', 'value': cookie_value}) request['uri'] = uri return request
Ответ зрителя
Ответ просмотра Функция в основном имеет одну задачу, и это должен пройти Set-Cookie заголовок к клиенту. Это необходимо, чтобы клиент установил файлы cookie X-версия-имя и X-версия-сброс Таким образом, клиент отправляет их в следующий запрос. Это важно, чтобы клиент не прыгал между версиями. У этой функции есть небольшая, но очень важная работа.
Код ответа просмотра
Полная версия доступна в GitHub Анкет
def lambda_handler(event, context): response = event['Records'][0]['cf']['response'] request = event['Records'][0]['cf']['request'] # Persist cookie, set the set-cookie header if 'set-cookie' not in response['headers']: response['headers']['set-cookie'] = [] request_headers = request['headers'] cookie_version_blue = 'X-Version-Name=Blue' cookie_version_green = 'X-Version-Name=Green' cookie_reset = 'X-Version-Reset' for cookie in request_headers.get('cookie', []): if cookie_version_blue in cookie['value']: response['headers']['set-cookie'].append( {'key': 'set-cookie', 'value': cookie_version_blue}) elif cookie_version_green in cookie['value']: response['headers']['set-cookie'].append( {'key': 'set-cookie', 'value': cookie_version_green}) elif cookie_reset in cookie['value']: response['headers']['set-cookie'].append( {'key': 'set-cookie', 'value': cookie['value']}) return response
Развертывание функций
Функции лямбда должны быть развернуты в регионе США-Востока-1, поскольку именно этот край лямбда @ Мы также должны использовать фиксированную версию и не можем использовать Последние псевдоним. Как обычный AWS SAM используется для определения и развертывания функций Lambda.
Шаблон SAM
Полная версия доступна в GitHub Анкет
ViewerRequestFunction: Type: AWS::Serverless::Function Properties: AutoPublishAlias: "true" Runtime: python3.7 MemorySize: 128 Timeout: 3 CodeUri: ./viewer-request Handler: handler.lambda_handler AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com - edgelambda.amazonaws.com Action: - sts:AssumeRole Policies: - SSMParameterReadPolicy: ParameterName: !Sub ${SsmConfigPath}/* - Version: "2012-10-17" Statement: Action: - lambda:GetFunction Effect: Allow Resource: "*" ViewerResponseFunction: Type: AWS::Serverless::Function Properties: AutoPublishAlias: "true" Runtime: python3.7 MemorySize: 128 Timeout: 3 CodeUri: ./viewer-response Handler: handler.lambda_handler AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com - edgelambda.amazonaws.com Action: - sts:AssumeRole Policies: - Version: "2012-10-17" Statement: Action: - lambda:GetFunction Effect: Allow Resource: "*"
Настройка Cloudfront
Наконец, нам нужно создать распределение CloudFront и установить функции лямбда для запроса запроса зрителя и триггеры ответа. Обычно CloudFront не будет использовать и передавать заголовки к кешу. Поскольку наша настройка зависит от двух файлов cookie, мы должны убедиться, что CloudFront передал их. Это сделано путем добавления их в WhitelistedNames. раздел. Поддержание подстановки, поэтому мы просто добавляем X-version-* к этому разделу.
Шаблон деформации облака
Полная версия доступна в GitHub Анкет
CloudFrontDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Comment: !Sub "Distribution for ${ProjectName}" DefaultCacheBehavior: AllowedMethods: - "GET" - "HEAD" - "OPTIONS" Compress: False DefaultTTL: 0 MaxTTL: 0 MinTTL: 0 ForwardedValues: QueryString: False Cookies: Forward: whitelist WhitelistedNames: - "X-Version-*" LambdaFunctionAssociations: - !If - ViewerRequestLambdaArnSet - EventType: viewer-request LambdaFunctionARN: !Ref ViewerRequestLambdaArn - !Ref AWS::NoValue - !If - ViewerResponseLambdaArnSet - EventType: viewer-response LambdaFunctionARN: !Ref ViewerResponseLambdaArn - !Ref AWS::NoValue TargetOriginId: !Sub ${ProjectName}-origin ViewerProtocolPolicy: redirect-to-https DefaultRootObject: !Ref DefaultRootObject Enabled: True Origins: - DomainName: !Sub ${StorageBucket}.s3.amazonaws.com Id: !Sub ${ProjectName}-origin S3OriginConfig: OriginAccessIdentity: !Sub origin-access-identity/cloudfront/${OriginAccessIdentity} PriceClass: PriceClass_100 Tags: - Key: Name Value: !Sub ${ProjectName}
Вывод
Несмотря на то, что Cloudfront не поддерживает эти методы развертывания из коробки Lambda, как и раньше, приходите на помощь. Универсальность AWS Lambda — это действительно чудо! Загрузите код и возьмите его для Spin!
Счастливый взлом!
Оригинал: «https://dev.to/jimmydqv/cloudfront-deployments-with-lambda-edge-4jmh»