AWS ECS 通过 Cloudformation 创建计划任务 (cron)
AWS ECS Create Scheduled Tasks (cron) via Cloudformation
我们想通过 CloudFormation 在 AWS ECS 中创建 ScheduledTasks。是否有通过 boto 或 cloudformation 创建的编程方式?
您可以使用 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。
其他资源:
为了在 CloudFormation 中定义计划的 ECS 任务,您需要定义一个 "AWS::Events::Rule" 资源并将 ECS 任务作为目标。
"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"]
}
}
]
}
}
Troposphere 现在允许定义 ECS
计划任务,你需要三个资源,
任务定义:
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>']
),
],
)
角色运行任务:
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"),
}
)
)],
),
),
],
)
调度任务的事件规则:
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),
),
),
]
)
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/
我们想通过 CloudFormation 在 AWS ECS 中创建 ScheduledTasks。是否有通过 boto 或 cloudformation 创建的编程方式?
您可以使用 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。
其他资源:
为了在 CloudFormation 中定义计划的 ECS 任务,您需要定义一个 "AWS::Events::Rule" 资源并将 ECS 任务作为目标。
"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"]
}
}
]
}
}
Troposphere 现在允许定义 ECS
计划任务,你需要三个资源,
任务定义:
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>'] ), ], )
角色运行任务:
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"), } ) )], ), ), ], )
调度任务的事件规则:
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), ), ), ] )
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/