CloudFormationテンプレートで、次のEcsParametersを持つスケジュールされたタスク(CloudWatchイベントルール)を作成しようとしています。
EcsParameters:
LaunchType: FARGATE
NetworkConfiguration:
AwsVpcConfiguration:
AssignPublicIp: !Ref PublicIpAssignment
SecurityGroups:
- !Ref EcsSecurityGroups
Subnets:
- !Ref SubnetName
TaskCount: 1
TaskDefinitionArn: !Ref TaskDefinitionOne
私のECS CLusterはEC2ではなくFargateで起動し、サービスを実行していません(ユースケースは長時間実行するプロセスを必要とせず、イベントルールからタスクを直接スケジュールします)。
このテンプレートを(LaunchType
およびNetworkConfiguration
を使用して)実行すると、スタックの作成は次のエラーで失敗します。
サポートされていないプロパティNetworkConfigurationが発生しました
別の方法として、スケジュールされたタスクをAWS CLIから起動してみましたが、ネットワーク構成と起動タイプのオプションもそこで利用できないようです:
パラメータの検証に失敗しました:Targets [0] .EcsParametersの不明なパラメータ: "LaunchType"、次のいずれかである必要があります:TaskDefinitionArn、TaskCount
AWSドキュメント自体の このページ によると、LaunchType
のNetworkConfiguration
セクションにEcsParameters
とTargets
を指定できるはずです] _のProperties
のAWS::Events::Rule
資源。
私が試すことができることは何ですか?
CloudFormationは、FargateタスクをCloudWatchイベントルールの直接のターゲットとして実行するために必要なパラメーターにまだ対応していません。それまでの間、Fargateタスクを実行するLambda関数をルールのターゲットとすることで、同じ結果を得ることができます。
これを機能させるには、イベントルールがLambda関数に対するlambda:InvokeFunction
権限を必要とし、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環境に渡すことができます。次に、スケジュールと呼び出しの権限を1つまたは複数の個別のスタックで定義し、Lambda関数への入力を介して各タスクのTaskDefinition
を渡します。これにより、クラスターごとに1つのLambdaを持つことができますが、必要な数の異なるタスクを使用できます。カスタムコマンド文字列や他のコンテナオーバーライドをLambda入力に追加して、run_task
のoverrides
パラメータを介して渡すこともできます。
編集#2:CFテンプレートで使用できるFargate TaskDefinitionの例を次に示します。
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
AWSは今日(2019年7月15日)までにドキュメントを更新していませんが、最初の投稿者の説明どおりに機能しています。
1日の調査の後、AWSはまだCloudFormationを介してこれに対するサポートをリリースしていないようです。ただし、ここではaws events put-targets
CLIのコマンド。
このメソッドは、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ドキュメントのput-ruleについて と for put-targets を参照してください。
ドキュメントのルールの例を以下に示します。
aws events put-rule --name "DailyLambdaFunction" --schedule-expression "cron(0 9 * * ? *)"
私のために働いたput-targetsコマンドはこれです:
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"}'