Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(events-targets): ecs:TagResource permission #28898

Merged
merged 10 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
"VpcPublicSubnet1Subnet5C2D37C4": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "Vpc8378EB38"
},
"AvailabilityZone": {
"Fn::Select": [
0,
Expand All @@ -44,21 +41,24 @@
"Key": "Name",
"Value": "aws-ecs-integ-ecs/Vpc/PublicSubnet1"
}
]
],
"VpcId": {
"Ref": "Vpc8378EB38"
}
}
},
"VpcPublicSubnet1RouteTable6C95E38E": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {
"Ref": "Vpc8378EB38"
},
"Tags": [
{
"Key": "Name",
"Value": "aws-ecs-integ-ecs/Vpc/PublicSubnet1"
}
]
],
"VpcId": {
"Ref": "Vpc8378EB38"
}
}
},
"VpcPublicSubnet1RouteTableAssociation97140677": {
Expand All @@ -75,12 +75,12 @@
"VpcPublicSubnet1DefaultRoute3DA9E72A": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": {
"Ref": "VpcPublicSubnet1RouteTable6C95E38E"
},
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {
"Ref": "VpcIGWD7BA715C"
},
"RouteTableId": {
"Ref": "VpcPublicSubnet1RouteTable6C95E38E"
}
},
"DependsOn": [
Expand All @@ -102,15 +102,15 @@
"VpcPublicSubnet1NATGateway4D7517AA": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"SubnetId": {
"Ref": "VpcPublicSubnet1Subnet5C2D37C4"
},
"AllocationId": {
"Fn::GetAtt": [
"VpcPublicSubnet1EIPD7E02669",
"AllocationId"
]
},
"SubnetId": {
"Ref": "VpcPublicSubnet1Subnet5C2D37C4"
},
"Tags": [
{
"Key": "Name",
Expand All @@ -126,9 +126,6 @@
"VpcPrivateSubnet1Subnet536B997A": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "Vpc8378EB38"
},
"AvailabilityZone": {
"Fn::Select": [
0,
Expand All @@ -152,21 +149,24 @@
"Key": "Name",
"Value": "aws-ecs-integ-ecs/Vpc/PrivateSubnet1"
}
]
],
"VpcId": {
"Ref": "Vpc8378EB38"
}
}
},
"VpcPrivateSubnet1RouteTableB2C5B500": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {
"Ref": "Vpc8378EB38"
},
"Tags": [
{
"Key": "Name",
"Value": "aws-ecs-integ-ecs/Vpc/PrivateSubnet1"
}
]
],
"VpcId": {
"Ref": "Vpc8378EB38"
}
}
},
"VpcPrivateSubnet1RouteTableAssociation70C59FA6": {
Expand All @@ -183,12 +183,12 @@
"VpcPrivateSubnet1DefaultRouteBE02A9ED": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": {
"Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
},
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": {
"Ref": "VpcPublicSubnet1NATGateway4D7517AA"
},
"RouteTableId": {
"Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
}
}
},
Expand All @@ -206,11 +206,11 @@
"VpcVPCGWBF912B6E": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": {
"Ref": "Vpc8378EB38"
},
"InternetGatewayId": {
"Ref": "VpcIGWD7BA715C"
},
"VpcId": {
"Ref": "Vpc8378EB38"
}
}
},
Expand Down Expand Up @@ -412,8 +412,6 @@
"EcsClusterDefaultAutoScalingGroupASGC1A785DB": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"MaxSize": "1",
"MinSize": "1",
"LaunchTemplate": {
"LaunchTemplateId": {
"Ref": "EcsClusterDefaultAutoScalingGroupLaunchTemplate3719972A"
Expand All @@ -425,6 +423,8 @@
]
}
},
"MaxSize": "1",
"MinSize": "1",
"Tags": [
{
"Key": "Name",
Expand Down Expand Up @@ -577,12 +577,6 @@
"Code": {
"ZipFile": "import boto3, json, os, time\n\necs = boto3.client('ecs')\nautoscaling = boto3.client('autoscaling')\n\n\ndef lambda_handler(event, context):\n print(json.dumps(dict(event, ResponseURL='...')))\n cluster = os.environ['CLUSTER']\n snsTopicArn = event['Records'][0]['Sns']['TopicArn']\n lifecycle_event = json.loads(event['Records'][0]['Sns']['Message'])\n instance_id = lifecycle_event.get('EC2InstanceId')\n if not instance_id:\n print('Got event without EC2InstanceId: %s', json.dumps(dict(event, ResponseURL='...')))\n return\n\n instance_arn = container_instance_arn(cluster, instance_id)\n print('Instance %s has container instance ARN %s' % (lifecycle_event['EC2InstanceId'], instance_arn))\n\n if not instance_arn:\n return\n\n task_arns = container_instance_task_arns(cluster, instance_arn)\n\n if task_arns:\n print('Instance ARN %s has task ARNs %s' % (instance_arn, ', '.join(task_arns)))\n\n while has_tasks(cluster, instance_arn, task_arns):\n time.sleep(10)\n\n try:\n print('Terminating instance %s' % instance_id)\n autoscaling.complete_lifecycle_action(\n LifecycleActionResult='CONTINUE',\n **pick(lifecycle_event, 'LifecycleHookName', 'LifecycleActionToken', 'AutoScalingGroupName'))\n except Exception as e:\n # Lifecycle action may have already completed.\n print(str(e))\n\n\ndef container_instance_arn(cluster, instance_id):\n \"\"\"Turn an instance ID into a container instance ARN.\"\"\"\n arns = ecs.list_container_instances(cluster=cluster, filter='ec2InstanceId==' + instance_id)['containerInstanceArns']\n if not arns:\n return None\n return arns[0]\n\ndef container_instance_task_arns(cluster, instance_arn):\n \"\"\"Fetch tasks for a container instance ARN.\"\"\"\n arns = ecs.list_tasks(cluster=cluster, containerInstance=instance_arn)['taskArns']\n return arns\n\ndef has_tasks(cluster, instance_arn, task_arns):\n \"\"\"Return True if the instance is running tasks for the given cluster.\"\"\"\n instances = ecs.describe_container_instances(cluster=cluster, containerInstances=[instance_arn])['containerInstances']\n if not instances:\n return False\n instance = instances[0]\n\n if instance['status'] == 'ACTIVE':\n # Start draining, then try again later\n set_container_instance_to_draining(cluster, instance_arn)\n return True\n\n task_count = None\n\n if task_arns:\n # Fetch details for tasks running on the container instance\n tasks = ecs.describe_tasks(cluster=cluster, tasks=task_arns)['tasks']\n if tasks:\n # Consider any non-stopped tasks as running\n task_count = sum(task['lastStatus'] != 'STOPPED' for task in tasks) + instance['pendingTasksCount']\n\n if not task_count:\n # Fallback to instance task counts if detailed task information is unavailable\n task_count = instance['runningTasksCount'] + instance['pendingTasksCount']\n\n print('Instance %s has %s tasks' % (instance_arn, task_count))\n\n return task_count > 0\n\ndef set_container_instance_to_draining(cluster, instance_arn):\n ecs.update_container_instances_state(\n cluster=cluster,\n containerInstances=[instance_arn], status='DRAINING')\n\n\ndef pick(dct, *keys):\n \"\"\"Pick a subset of a dict.\"\"\"\n return {k: v for k, v in dct.items() if k in keys}\n"
},
"Role": {
"Fn::GetAtt": [
"EcsClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole94543EDA",
"Arn"
]
},
"Environment": {
"Variables": {
"CLUSTER": {
Expand All @@ -591,6 +585,12 @@
}
},
"Handler": "index.lambda_handler",
"Role": {
"Fn::GetAtt": [
"EcsClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole94543EDA",
"Arn"
]
},
"Runtime": "python3.9",
"Tags": [
{
Expand Down Expand Up @@ -624,15 +624,15 @@
"EcsClusterDefaultAutoScalingGroupDrainECSHookFunctionTopic8F34E394": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Protocol": "lambda",
"TopicArn": {
"Ref": "EcsClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicACD2D4A4"
},
"Endpoint": {
"Fn::GetAtt": [
"EcsClusterDefaultAutoScalingGroupDrainECSHookFunctionE17A5F5E",
"Arn"
]
},
"Protocol": "lambda",
"TopicArn": {
"Ref": "EcsClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicACD2D4A4"
}
}
},
Expand Down Expand Up @@ -699,9 +699,9 @@
"AutoScalingGroupName": {
"Ref": "EcsClusterDefaultAutoScalingGroupASGC1A785DB"
},
"LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING",
"DefaultResult": "CONTINUE",
"HeartbeatTimeout": 300,
"LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING",
"NotificationTargetARN": {
"Ref": "EcsClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicACD2D4A4"
},
Expand Down Expand Up @@ -911,6 +911,26 @@
"Ref": "ScheduledEc2TaskScheduledTaskDef56328BA4"
}
},
{
"Action": "ecs:TagResource",
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:ecs:",
{
"Ref": "AWS::Region"
},
":*:task/",
{
"Ref": "EcsCluster97242B84"
},
"/*"
]
]
}
},
{
"Action": "iam:PassRole",
"Effect": "Allow",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.