AWS ECS通过Cloudformation创建计划任务(cron)

时间:2017-06-13 16:39:03

标签: amazon-web-services amazon-cloudformation amazon-ecs

我们希望通过CloudFormation在AWS ECS中创建ScheduledTasks。是否有通过boto或cloudformation创建的编程方式?

3 个答案:

答案 0 :(得分:17)

为了在CloudFormation中定义计划的ECS任务,您需要定义一个以ECS任务为目标的“AWS :: Events :: Rule”资源。

"TaskSchedule": {
  "Type": "AWS::Events::Rule",
  "Properties": {
    "Description": "dump data every workday at 10",
    "Name": "dump-data",
    "ScheduleExpression": "cron(0 10 ? * MON-FRI *)",
    "State": "ENABLED",
    "Targets": [
      {
        "Id": "dump-data-ecs-task",
        "RoleArn": {
          "Fn::GetAtt": ["TaskSchedulerRole", "Arn"]
        },
        "EcsParameters": {
          "TaskDefinitionArn": {
            "Ref": "TaskDefinition"
          },
          "TaskCount": 1
        },
        "Arn": {
          "Fn::GetAtt": ["EcsCluster", "Arn"]
        }
      }
    ]
  }
}

答案 1 :(得分:6)

对流层现在允许定义ECS计划任务,你需要三个资源,

  1. 任务定义:

    from troposphere.ecs import (
        ContainerDefinition,
        TaskDefinition,
    )
    
    scheduled_worker_task_definition = TaskDefinition(
        "ScheduledWorkerTask",
        template=template,
        ContainerDefinitions=[
            ContainerDefinition(
                Name="ScheduledWorker",
                Cpu=200,
                Memory=300,
                Essential=True,
                Image="<image>",
                EntryPoint=['<entry_point>']
            ),  
        ],  
    )
    
  2. 运行任务的角色:

    from troposphere import iam
    
    run_task_role = iam.Role(
        "RunTaskRole",
        template=template,
        AssumeRolePolicyDocument=dict(Statement=[dict(
            Effect="Allow",
            Principal=dict(Service=["events.amazonaws.com"]),
            Action=["sts:AssumeRole"],
        )]),
        Path="/",
        Policies=[
            iam.Policy(
                PolicyName="RunTaskPolicy",
                PolicyDocument=dict(
                    Statement=[dict(
                        Effect="Allow",
                        Action=[
                            "ecs:RunTask",
                        ],
                        Resource=["*"],
                        Condition=dict(
                            ArnEquals={
                                "ecs:cluster": GetAtt(cluster, "Arn"),
                            }
                        )
                    )],
                ),
            ),
        ],
    )
    
  3. 计划任务的事件规则:

    from troposphere.events import Rule, Target, EcsParameters
    
    Rule(
        "SchedulingRule",
        template=template,
        Description="My schedule task rule",
        State="ENABLED",
        ScheduleExpression="rate(30 minutes)",
        Targets=[
            Target(
                Id="ScheduledWorkerTaskDefinitionTarget",
                RoleArn=GetAtt(run_task_role, "Arn"),
                Arn=GetAtt(cluster, "Arn"),
                EcsParameters=EcsParameters(
                    TaskCount=1,
                    TaskDefinitionArn=Ref(scheduled_worker_task_definition),
                ),
            ),
        ]
    )
    
  4. JSON输出的位置如下:

        ...
        "ScheduledWorkerTask": {
            "Condition": "Deploy",
            "Properties": {
                "ContainerDefinitions": [
                    {
                        "Cpu": 200,
                        "EntryPoint": [
                            "<entry_point>"
                        ],
                        "Essential": "true",
                        "Image": {
                            "Fn::Join": [
                                "",
                                [
                                    {
                                        "Ref": "AWS::AccountId"
                                    },
                                    ".dkr.ecr.",
                                    {
                                        "Ref": "AWS::Region"
                                    },
                                    ".amazonaws.com/",
                                    {
                                        "Ref": "ApplicationRepository"
                                    },
                                    ":",
                                    "<image>"
                                ]
                            ]
                        },
                        "Memory": 300,
                        "Name": "ScheduledWorker"
                    }
                ]
            },
            "Type": "AWS::ECS::TaskDefinition"
        },
    
        "SchedulingRule": {
            "Properties": {
                "Description": "My schedule task rule",
                "ScheduleExpression": "rate(30 minutes)",
                "State": "ENABLED",
                "Targets": [
                    {
                        "Arn": {
                            "Fn::GetAtt": [
                                "Cluster",
                                "Arn"
                            ]
                        },
                        "EcsParameters": {
                            "TaskCount": 1,
                            "TaskDefinitionArn": {
                                "Ref": "ScheduledWorkerTask"
                            }
                        },
                        "Id": "ScheduledWorkerTaskDefinitionTarget",
                        "RoleArn": {
                            "Fn::GetAtt": [
                                "RunTaskRole",
                                "Arn"
                            ]
                        }
                    }
                ]
            },
            "Type": "AWS::Events::Rule"
        },
    
        "RunTaskRole": {
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Statement": [
                        {
                            "Action": [
                                "sts:AssumeRole"
                            ],
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "events.amazonaws.com"
                                ]
                            }
                        }
                    ]
                },
                "Path": "/",
                "Policies": [
                    {
                        "PolicyDocument": {
                            "Statement": [
                                {
                                    "Action": [
                                        "ecs:RunTask"
                                    ],
                                    "Condition": {
                                        "ArnEquals": {
                                            "ecs:cluster": {
                                                "Fn::GetAtt": [
                                                    "Cluster",
                                                    "Arn"
                                                ]
                                            }
                                        }
                                    },
                                    "Effect": "Allow",
                                    "Resource": [
                                        "*"
                                    ]
                                }
                            ]
                        },
                        "PolicyName": "RunTaskPolicy"
                    }
                ]
            },
            "Type": "AWS::IAM::Role"
        },
        ...
    

    https://jeanphix.github.io/2017/10/04/ecs-scheduled-cron-task-with-cloudformation/

    的更多信息

答案 2 :(得分:1)

您可以使用boto和cloudformation执行此操作。如果您使用cloudformation进行操作,则需要使用Lambda-backed custom resource。你也可以用对流层来做到这一点。

对流层示例:

# Read in the code
fname = "lambda_code.py"
try:
  with open(fname) as target:
    code = target.readlines()
except Exception as e:
  print(e)

# Create the custom resource.
CustomResource = template.add_resource(Function(
  "CustomResource",
  Description="Creates and Runs a Lambda function.",
  FunctionName="myFunctionName",
  Code=Code(
    ZipFile=Join("",code)
  ),
  Runtime="python2.7",
  Role=GetAtt("lambaRole","Arn"),
  Handler="index.decide_action",
  MemorySize='128',
  Timeout='10'
))      

关于在boto中创建任务,请查看Boto3 Documentation

其他资源: