создание 'Target' для правила события cloudwatch через cloudformation для задачи типа запуска fargate - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь создать запланированное задание (правило событий CloudWatch) в своем шаблоне CloudFormation, которое будет иметь следующие параметры EcsParameters:

EcsParameters:
        LaunchType: FARGATE
        NetworkConfiguration: 
          AwsVpcConfiguration:
            AssignPublicIp: !Ref PublicIpAssignment
            SecurityGroups:
              - !Ref EcsSecurityGroups
            Subnets:
              - !Ref SubnetName
        TaskCount: 1
        TaskDefinitionArn: !Ref TaskDefinitionOne

Мой ECS CLuster запущен на Fargate, а не на EC2, и у меня НЕ работает служба (сценарий использования не требует длительного процесса, непосредственно планируя задачи из правил событий).

Всякий раз, когда я запускаю этот шаблон (с LaunchType и NetworkConfiguration), создание стека завершается неудачей, с этой ошибкой:

Обнаружено неподдерживаемое свойство NetworkConfiguration


В качестве альтернативы я также попытался запустить запланированное задание из интерфейса командной строки AWS, но, похоже, параметры конфигурации сети и типа запуска там также недоступны:

Проверка параметров не удалась: Неизвестный параметр в Targets [0] .EcsParameters: «LaunchType», должен быть одним из: TaskDefinitionArn, TaskCount


Согласно этой странице в самой документации AWS, я должен иметь возможность указать LaunchType и NetworkConfiguration в моем разделе EcsParameters в Targets в Properties AWS::Events::Rule ресурс.

Могу ли я попробовать что-нибудь, что сработает?

Ответы [ 3 ]

0 голосов
/ 27 сентября 2018

CloudFormation еще не ознакомился с параметрами, необходимыми для запуска задачи Fargate в качестве прямой цели правила событий CloudWatch. В то же время, вы можете достичь того же результата, установив целевое правило для лямбда-функции, которая запускает задачу Fargate.

Чтобы это работало, для правила событий потребуется разрешение lambda:InvokeFunction для функции Lambda, а для функции Lambda потребуется разрешение ecs:RunTask и iam:PassRole для соответствующих ресурсов (в дополнение к обычным разрешениям журналов в AWSLambdaBasicExecutionRole ).

Редактировать : Вот пример шаблона CF, который показывает, о чем я говорю. (Он собран и упрощен из того, что мы используем, поэтому не тестируется, но, надеюсь, иллюстрирует процесс.)

Parameters:
  #ClusterName
  #Subnets
  #SecurityGroups
  #CronExpression
  #TaskDefinitionArn
  #TaskRoleArn
  #ExecutionRoleArn

Resources:
  FargateLauncherRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${AWS::StackName}-FargateLauncher-${AWS::Region}
      AssumeRolePolicyDocument:
        Statement:
          -
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Path: /

  FargateLauncherPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: !Sub ${AWS::StackName}-FargateLauncher-${AWS::Region}
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          -
            Sid: RunTaskAccess
            Effect: Allow
            Action:
              - ecs:RunTask
            Resource: '*'
          -
            Sid: PassRoleAccess
            Effect: Allow
            Action:
              - iam:PassRole
            Resource:
              # whatever you have defined in your TaskDefinition, if any
              - !Ref TaskRoleArn
              - !Ref ExecutionRoleArn
      Roles:
        - !Ref FargateLauncherRole

  FargateLauncher:
    Type: AWS::Lambda::Function
    DependsOn: FargateLauncherPolicy
    Properties:
      Environment:
        Variables:
          CLUSTER_NAME: !Ref ClusterName
          SUBNETS: !Ref Subnets
          SECURITY_GROUPS: !Ref SecurityGroups
      Handler: index.handler
      Role: !GetAtt FargateLauncherRole.Arn
      Runtime: python3.6
      Code:
        ZipFile: |
          from os import getenv
          from boto3 import client
          ecs = client('ecs')

          def handler(event, context):
            ecs.run_task(
              cluster=getenv('CLUSTER_NAME'),
              launchType='FARGATE',
              taskDefinition=event.get('taskDefinition'),
              count=1,
              platformVersion='LATEST',
              networkConfiguration={'awsvpcConfiguration': {
                'subnets': getenv('SUBNETS').split(','),
                'securityGroups': getenv('SECURITY_GROUPS').split(','),
                'assignPublicIp': 'DISABLED'
              }})

  Schedule:
    Type: AWS::Events::Rule
    Properties:
      ScheduleExpression: !Sub "cron(${CronExpression})"
      State: ENABLED
      Targets:
        -
          Id: fargate-launcher
          Arn: !GetAtt FargateLauncher.Arn
          Input: !Sub |
            {
              "taskDefinition": "${TaskDefinitionArn}"
            }

  InvokePermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref FargateLauncher
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt Schedule.Arn

Я определяю функцию Lambda в своем стеке кластера, где у меня уже есть параметры ClusterName, Subnets и SecurityGroups, и могу передать их непосредственно в среду Lambda. Затем расписание и разрешение вызова могут быть определены в одном или нескольких отдельных стеках, передавая TaskDefinition для каждой задачи через вход в функцию Lambda. Таким образом, вы можете иметь одну лямбду на кластер, но использовать столько разных задач, сколько необходимо. Вы также можете добавить пользовательскую строку команды и / или другие переопределения контейнеров к входу Lambda, который можно передать через параметр overrides из run_task.

Редактировать # 2 : Вот пример Fargate TaskDefinition, который может входить в шаблон CF:

TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    Family: !Ref Family
    Cpu: !Ref Cpu
    Memory: !Ref Memory
    NetworkMode: awsvpc
    ExecutionRoleArn: !Ref ExecutionRoleArn
    TaskRoleArn: !Ref TaskRoleArn
    RequiresCompatibilities:
      - FARGATE
    ContainerDefinitions:
      - Name: !Ref ContainerName
        Essential: true
        Image: !Ref Image
        LogConfiguration:
          LogDriver: awslogs
          Options:
            awslogs-group: !Ref LogGroup
            awslogs-region: !Ref AWS::Region
            awslogs-stream-prefix: !Ref LogPrefix
0 голосов
/ 15 июля 2019

Несмотря на то, что на сегодняшний день AWS не обновила документацию (15 июля 2019 г.), она работает так, как описано в первоначальном плакате.

0 голосов
/ 06 сентября 2018

После дня исследований кажется, что AWS все еще не выпустил поддержку этого, хотя CloudFormation. Однако есть альтернатива, которая работала с помощью команды aws events put-targets на клиенте.

Этот метод не работает для более старых версий cli. запустите это для обновления: pip install awscli --upgrade --user Это версия, на которой я сейчас нахожусь: aws-cli/1.16.9 Python/2.7.15 Darwin/17.7.0 botocore/1.11.9

Используйте команду aws events put-targets --rule <value> --targets <value>. Убедитесь, что у вас уже есть правило, определенное в вашем кластере. Если нет, вы можете сделать это с помощью aws events put-rule cmd. Обратитесь к документам AWS для пут-правила и для пут-целей .

Пример правила из документации приведен ниже:

aws events put-rule --name "DailyLambdaFunction" --schedule-expression "cron(0 9 * * ? *)"

Команда put-target, которая работала для меня, выглядит так:

aws events put-targets --rule cli-RS-rule --targets '{"Arn": "arn:aws:ecs:1234/cluster/clustername","EcsParameters": {"LaunchType": "FARGATE","NetworkConfiguration": {"awsvpcConfiguration": {"AssignPublicIp": "ENABLED", "SecurityGroups": [ "sg-id1233" ], "Subnets": [ "subnet-1234" ] }},"TaskCount": 1,"TaskDefinitionArn": "arn:aws:ecs:1234:task-definition/taskdef"},"Id": "sampleID111","RoleArn": "arn:aws:iam:1234:role/eventrole"}'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...