Всем привет.
Не так давно AWS добавил новую возможность запускать scheduled task, что как по мне, является весьма удобной фичей для выполнения некоторых задач. К сожалению, пока (надеюсь только пока) HashiCorp не добавила возможность управлять ними как ресурсом в terraform. Но есть способ как обойти эту (надеюсь) временную неприятность набором доступных в AWS сервисов и дальше я расскажу как это сделал я.
Решение которое я нашел это использовать AWS Cloudwatch Events, который будет запускать AWS ECS task, которое выполнится и завершится.
Ссылка на репозиторий с тераформ темплейтом: https://github.com/dark4igi/ecs-scheduled-task-using-terraform-example
В своем примере использую Fargate вариант запуска контейнеров, потому что так проще. Так же задание которое нужно выполнять это чтение таблицы DynamoDB и добавление в не новой записи со следующим Id и временем запуска контейнера, как по мне это отличный и наглядный пример, который не требует уникального имени как S3.
Вот пример кода который нужно выполнить по расписанию.
#!/bin/sh
jq --arg date "$(date)" --arg number "$(aws dynamodb scan --table-name "$TABLE" | jq .Count)" '.Id.N = ($number) | .Value.S = ($date)' template.json > item.json && echo 'generation done' || echo 'generation false'
aws dynamodb put-item --table-name "$TABLE" --item file://item.json && echo 'put done' || echo 'put false'
так же файл template.json
{
"Id": {
"N": ""
},
"Value": {
"S": ""
}
}
Dockerfile: закинуть скрирт и темплейт, добавить скрипту права на запуск, установить awscli и jq, CMD = script.sh
При запуске контейнера нужно передавать как аргумент название DynamoDB таблицы.
Для локального запуска нужно передавать еще и access_key и secret_key.
Для корректной работы наших ресурсов в AWS нам нужно создать роли для Cloudwatch Events, с возможностью запускать ECS task и роль для task, возможность работы с DynamoDB. Это описано в файле infra.tf и data.tf. Так же в infra.tf описано создание таблицы и кластера.
Так же нам потребуется Task definition, для запуска ECS task, описание в тех же файла.
Я использовал функцию terraform template_file что бы не хардкодить название таблицы в task definition.
Еще для запуска нам нужно VPC, subnet(s) и security group. Я использовал дефолтные, получении их id описано в data.tf.
Ну и самое важное создание aws_cloudwatch_event_rule и aws_cloudwatch_event_target описано в scheduled_task.tf
Для запуска и тестирования:
git clone
Раскомментировать и заполнить секцию provide
terraform init
terraform apply
После чего можно смотреть логи в Cloudwatch /ecs/cron-worker и проверять содержание DynamoDB таблицы.
P.S.:
Решение демонстрационное и может иметь кучу косяков безопасности.
Это моя первая статья и тоже может иметь кучу косяков.