Имеется уже созданный стек с Application Load Balancer, для которого требуется включить сбор логов в S3 корзину.
Общая документация – тут>>>.
CloudFormation стек и ресурсы уже созданы, поэтому тут просто пример добавления необходимых параметров и новых ресурсов для включения логгирования запросов балансировщика.
Запуск CloudFormation выполняется из Ansible с помощью модуля cloudformation
, и значения параметров будут заданы в файлах group_vars/envname.yml
.
Содержание
Параметры
ALBLogsBucketName
Добавляем первый параметр, который будет указывать имя корзины для логов:
... "ALBLogsBucketName": { "Description": "S3 bucket name for ALB logs", "Type": "String" } ...
В Ansible задаём значение, например файл group_vars/mobilebackend-dev.yml
:
... alb_logs_bucket_name: "mobilebackend-dev-alb-logs" ...
ALBRegionAccountID
Второй необходимый параметр – ALBRegionAccountID
, в котором задаём ALB Account ID, который зависит от региона. Полный список ID есть тут>>>.
Т.к. тут есть явная зависимость от региона – то его лучше задать в Mappings
шаблона.
Задаём маппинг для трёх регионов (у нас стеки могут быть только в них):
... "Mappings": { "ALBRegionAccountIDs": { "us-east-2": { "ALBRegionAccountID": "033677994240" }, "us-east-1": { "ALBRegionAccountID": "127311923021" }, "eu-west-1": { "ALBRegionAccountID": "156460612806" } }, ...
Далее используем Fn::FindInMap
для получения значений.
AWSAccountID
Для создания политики доступа к корзине – потребуется AWS Account ID, добавляем параметр для него:
... "AWSAccountID": { "Description": "AWS Console Account ID for S3 Bucket Policy", "Type": "String" } ...
И добавляем в Ansible.
Т.к. значение не зависит от рабочего окружения – передаём через group_vars/all.yml
:
... aws_account_id: "534***385" ...
Можно зашифровать с помощью ansible-vault
.
С параметрами вроде всё – переходим к ресурсам.
Ресурсы
Application Load Balancer attributes
Тут потребуется добавить несколько аттрибутов:
... "LoadBalancerAttributes" : [ { "Key": "idle_timeout.timeout_seconds", "Value": 50 }, { "Key": "routing.http2.enabled", "Value": true }, { "Key": "access_logs.s3.prefix" }, { "Key": "deletion_protection.enabled", "Value": true }, { "Key": "access_logs.s3.bucket", "Value": {"Ref": "ALBLogsBucketName"} }, { "Key": "access_logs.s3.enabled", "Value": true } ], ...
В access_logs.s3.bucket
передаём собственно имя корзины, в которую ALB будет складывать логи.
Кроме того – добавляем явное указание на зависимость ресурса ALB от корзины и её политики через аттрибут DependsOn
:
... "MBApploadBalancer" : { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "DependsOn": ["AlbLogsBucket", "BucketPolicy"], "Properties": { "Scheme": "internet-facing", ...
AWS::S3::Bucket
Добавляем создание корзины:
... "AlbLogsBucket": { "Type": "AWS::S3::Bucket", "DeletionPolicy": "Delete", "Properties": { "BucketName": { "Ref": "ALBLogsBucketName" } } }, ...
AWS::S3::BucketPolicy
Что бы ALB имел доступ на запись логов в корзину – создаём политику доступа к корзине:
... "BucketPolicy": { "Type": "AWS::S3::BucketPolicy", "Properties": { "PolicyDocument": { "Id": "MyPolicy", "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": { "Fn::Sub": [ "arn:aws:iam::${ALBRegionAccountID}:root", { "ALBRegionAccountID": { "Fn::FindInMap": [ "ALBRegionAccountIDs", {"Ref" : "StackRegion"}, "ALBRegionAccountID" ] } } ] } }, "Action": "s3:PutObject", "Resource": { "Fn::Join" : [ "", [ "arn:aws:s3:::", {"Ref" : "ALBLogsBucketName"}, "/AWSLogs/", {"Ref" : "AWSAccountID"}, "/*" ] ] } } ] }, "Bucket": { "Ref": "AlbLogsBucket" } } }, ...
Principal
: тут используемFn::Sub
, из которой формируем строку вида arn:aws:iam::033677994240:root, используя параметрStackRegion
для выборки значенияALBRegionAccountID
изMappings
, который создали выше- Resource: используя Fn::Join – формируем строку вида arn:aws:s3:::mobilebackend-dev-alb-logs/AWSLogs/534***385/*
Вроде ОК?
Тут я использую скрипт, аналогичный этому>>> – запускаем проверку:
[simterm]
$ ./ansible_exec.sh -c Tags: infra Env: mobilebackend-dev ... Running dry-run... ... Dry-run check passed. ... PLAY RECAP **** dev.backend-bastion.example.world : ok=3 changed=1 unreachable=0 failed=0 Provisioning done.
[/simterm]
Проверяем аттрибуты ALB:
И корзину с логами:
Готово.
P.S. Позже сюда ещё добавил LifecycleConfiguration
с ExpirationInDays
:
... "AlbLogsBucket": { "Type": "AWS::S3::Bucket", "DeletionPolicy": "Delete", "Properties": { "BucketName": { "Ref": "ALBLogsBucketName" }, "LifecycleConfiguration": { "Rules": [ { "Id": "CleanLogs", "Prefix": "", "Status": "Enabled", "ExpirationInDays": { "Ref": "ALBLogsExpirationInDays" } } ] } } }, ...
ALBLogsExpirationInDays
опять-таки передаём в Ansible роль:
... ALBLogsExpirationInDays: "{{ alb_logs_expiration_in_days }}" ...
Из файлов в group_vars
:
... alb_logs_expiration_in_days: 3 ...
Вот теперь – точно готово.