Skip to content

Commit 86c60b4

Browse files
authored
ecs: integration test and new purge parameters (#1716)
ecs: integration test and new purge parameters SUMMARY Make the ecs_cluster integration test work again ecs_service - new parameter purge_placement_constraints and purge_placement_strategy. Otherwise it is impossible to remove those placements without breaking backwards compatibility. purge_placement_constraints in the integration test purge_placement_strategy in the integration test required by mattclay/aws-terminator#210 (comment) ISSUE TYPE Bugfix Pull Request Docs Pull Request Feature Pull Request COMPONENT NAME ecs_service ADDITIONAL INFORMATION works for me again ansible-test integration --python 3.10 ecs_cluster --docker --allow-unsupported ... PLAY RECAP ********************************************************************* testhost : ok=143 changed=69 unreachable=0 failed=0 skipped=1 rescued=0 ignored=6 Reviewed-by: Mark Chappell Reviewed-by: Markus Bergholz <[email protected]> Reviewed-by: Alina Buzachis Reviewed-by: Mike Graves <[email protected]>
1 parent b5eefc1 commit 86c60b4

File tree

10 files changed

+1516
-1357
lines changed

10 files changed

+1516
-1357
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
minor_changes:
2+
- ecs_service - new parameter ``purge_placement_strategy`` to have the ability to remove the placement strategy of an ECS Service (https://github.com/ansible-collections/community.aws/pull/1716).
3+
- ecs_service - new parameter ``purge_placement_constraints`` to have the ability to remove the placement constraints of an ECS Service (https://github.com/ansible-collections/community.aws/pull/1716).
4+
trivial:
5+
- ecs_cluster - rework and repair ecs_cluster integration test.
6+
deprecated_features:
7+
- ecs_service - In a release after 2024-06-01, tha default value of ``purge_placement_strategy`` will be change from ``false`` to ``true`` (https://github.com/ansible-collections/community.aws/pull/1716).
8+
- ecs_service - In a release after 2024-06-01, tha default value of ``purge_placement_constraints`` will be change from ``false`` to ``true`` (https://github.com/ansible-collections/community.aws/pull/1716).

plugins/modules/ecs_service.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,14 @@
148148
description: A cluster query language expression to apply to the constraint.
149149
required: false
150150
type: str
151+
purge_placement_constraints:
152+
version_added: 5.3.0
153+
description:
154+
- Toggle overwriting of existing placement constraints. This is needed for backwards compatibility.
155+
- By default I(purge_placement_constraints=false). In a release after 2024-06-01 this will be changed to I(purge_placement_constraints=true).
156+
required: false
157+
type: bool
158+
default: false
151159
placement_strategy:
152160
description:
153161
- The placement strategy objects to use for tasks in your service. You can specify a maximum of 5 strategy rules per service.
@@ -162,6 +170,14 @@
162170
field:
163171
description: The field to apply the placement strategy against.
164172
type: str
173+
purge_placement_strategy:
174+
version_added: 5.3.0
175+
description:
176+
- Toggle overwriting of existing placement strategy. This is needed for backwards compatibility.
177+
- By default I(purge_placement_strategy=false). In a release after 2024-06-01 this will be changed to I(purge_placement_strategy=true).
178+
required: false
179+
type: bool
180+
default: false
165181
force_deletion:
166182
description:
167183
- Forcibly delete the service. Required when deleting a service with >0 scale, or no target group.
@@ -396,7 +412,9 @@
396412
returned: always
397413
type: int
398414
loadBalancers:
399-
description: A list of load balancer objects
415+
description:
416+
- A list of load balancer objects
417+
- Updating the loadbalancer configuration of an existing service requires botocore>=1.24.14.
400418
returned: always
401419
type: complex
402420
contains:
@@ -822,7 +840,8 @@ def create_service(self, service_name, cluster_name, task_definition, load_balan
822840
def update_service(self, service_name, cluster_name, task_definition, desired_count,
823841
deployment_configuration, placement_constraints, placement_strategy,
824842
network_configuration, health_check_grace_period_seconds,
825-
force_new_deployment, capacity_provider_strategy, load_balancers):
843+
force_new_deployment, capacity_provider_strategy, load_balancers,
844+
purge_placement_constraints, purge_placement_strategy):
826845
params = dict(
827846
cluster=cluster_name,
828847
service=service_name,
@@ -834,9 +853,15 @@ def update_service(self, service_name, cluster_name, task_definition, desired_co
834853
params['placementConstraints'] = [{key: value for key, value in constraint.items() if value is not None}
835854
for constraint in placement_constraints]
836855

856+
if purge_placement_constraints and not placement_constraints:
857+
params['placementConstraints'] = []
858+
837859
if placement_strategy:
838860
params['placementStrategy'] = placement_strategy
839861

862+
if purge_placement_strategy and not placement_strategy:
863+
params['placementStrategy'] = []
864+
840865
if network_configuration:
841866
params['networkConfiguration'] = network_configuration
842867
if force_new_deployment:
@@ -907,6 +932,7 @@ def main():
907932
expression=dict(required=False, type='str')
908933
)
909934
),
935+
purge_placement_constraints=dict(required=False, default=False, type='bool'),
910936
placement_strategy=dict(
911937
required=False,
912938
default=[],
@@ -917,6 +943,7 @@ def main():
917943
field=dict(type='str'),
918944
)
919945
),
946+
purge_placement_strategy=dict(required=False, default=False, type='bool'),
920947
health_check_grace_period_seconds=dict(required=False, type='int'),
921948
network_configuration=dict(required=False, type='dict', options=dict(
922949
subnets=dict(type='list', elements='str'),
@@ -1061,6 +1088,8 @@ def main():
10611088
module.params['force_new_deployment'],
10621089
capacityProviders,
10631090
updatedLoadBalancers,
1091+
module.params['purge_placement_constraints'],
1092+
module.params['purge_placement_strategy'],
10641093
)
10651094

10661095
else:

tests/integration/targets/ecs_cluster/aliases

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
# reason: slow
2-
# Tests take around 15 minutes to run
3-
unsupported
1+
time=20m
42

53
cloud/aws
64

tests/integration/targets/ecs_cluster/defaults/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ user_data: |
44
echo ECS_CLUSTER={{ ecs_cluster_name }} >> /etc/ecs/ecs.config
55
66
ecs_service_name: "{{ resource_prefix }}-service"
7+
ecs_service_role_name: "ansible-test-ecsServiceRole-{{ tiny_prefix }}"
8+
ecs_task_role_name: "ansible-test-ecsServiceRole-task-{{ tiny_prefix }}"
79
ecs_task_image_path: nginx
810
ecs_task_name: "{{ resource_prefix }}-task"
911
ecs_task_memory: 128
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
dependencies: []
1+
dependencies:
2+
- role: setup_botocore_pip
3+
vars:
4+
botocore_version: "1.24.14"
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
- name: ensure IAM service role exists
2+
iam_role:
3+
name: "{{ ecs_service_role_name }}"
4+
assume_role_policy_document: "{{ lookup('file','ecs-trust-policy.json') }}"
5+
state: present
6+
create_instance_profile: yes
7+
managed_policy:
8+
- AmazonEC2ContainerServiceRole
9+
wait: True
10+
11+
- name: ensure AWSServiceRoleForECS role exists
12+
iam_role_info:
13+
name: AWSServiceRoleForECS
14+
register: iam_role_result
15+
16+
# # This should happen automatically with the right permissions...
17+
#- name: fail if AWSServiceRoleForECS role does not exist
18+
# fail:
19+
# msg: >
20+
# Run `aws iam create-service-linked-role --aws-service-name=ecs.amazonaws.com ` to create
21+
# a linked role for AWS VPC load balancer management
22+
# when: not iam_role_result.iam_roles
23+
24+
- name: create a VPC to work in
25+
ec2_vpc_net:
26+
cidr_block: 10.0.0.0/16
27+
state: present
28+
name: '{{ resource_prefix }}_ecs_cluster'
29+
resource_tags:
30+
Name: '{{ resource_prefix }}_ecs_cluster'
31+
register: setup_vpc
32+
33+
- name: create a key pair to use for creating an ec2 instance
34+
ec2_key:
35+
name: '{{ resource_prefix }}_ecs_cluster'
36+
state: present
37+
when: ec2_keypair is not defined # allow override in cloud-config-aws.ini
38+
register: setup_key
39+
40+
- name: create subnets
41+
ec2_vpc_subnet:
42+
az: '{{ aws_region }}{{ item.zone }}'
43+
tags:
44+
Name: '{{ resource_prefix }}_ecs_cluster-subnet-{{ item.zone }}'
45+
vpc_id: '{{ setup_vpc.vpc.id }}'
46+
cidr: "{{ item.cidr }}"
47+
state: present
48+
register: setup_subnet
49+
with_items:
50+
- zone: a
51+
cidr: 10.0.1.0/24
52+
- zone: b
53+
cidr: 10.0.2.0/24
54+
55+
- name: create an internet gateway so that ECS agents can talk to ECS
56+
ec2_vpc_igw:
57+
vpc_id: '{{ setup_vpc.vpc.id }}'
58+
state: present
59+
register: igw
60+
61+
- name: create a security group to use for creating an ec2 instance
62+
ec2_group:
63+
name: '{{ resource_prefix }}_ecs_cluster-sg'
64+
description: 'created by Ansible integration tests'
65+
state: present
66+
vpc_id: '{{ setup_vpc.vpc.id }}'
67+
rules: # allow all ssh traffic but nothing else
68+
- ports: 22
69+
cidr_ip: 0.0.0.0/0
70+
register: setup_sg
71+
72+
- set_fact:
73+
# As a lookup plugin we don't have access to module_defaults
74+
connection_args:
75+
region: "{{ aws_region }}"
76+
aws_access_key: "{{ aws_access_key }}"
77+
aws_secret_key: "{{ aws_secret_key }}"
78+
aws_security_token: "{{ security_token | default(omit) }}"
79+
no_log: True
80+
81+
- name: set image id fact
82+
set_fact:
83+
ecs_image_id: "{{ lookup('aws_ssm', '/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id', **connection_args) }}"
84+
85+
- name: provision ec2 instance to create an image
86+
ec2_instance:
87+
key_name: '{{ ec2_keypair|default(setup_key.key.name) }}'
88+
instance_type: t3.micro
89+
state: present
90+
image_id: '{{ ecs_image_id }}'
91+
wait: yes
92+
user_data: "{{ user_data }}"
93+
instance_role: "{{ ecs_service_role_name }}"
94+
tags:
95+
Name: '{{ resource_prefix }}_ecs_agent'
96+
security_group: '{{ setup_sg.group_id }}'
97+
vpc_subnet_id: '{{ setup_subnet.results[0].subnet.id }}'
98+
register: setup_instance
99+
100+
- name: create target group
101+
elb_target_group:
102+
name: "{{ ecs_target_group_name }}1"
103+
state: present
104+
protocol: HTTP
105+
port: 8080
106+
modify_targets: no
107+
vpc_id: '{{ setup_vpc.vpc.id }}'
108+
target_type: instance
109+
health_check_interval: 5
110+
health_check_timeout: 2
111+
healthy_threshold_count: 2
112+
unhealthy_threshold_count: 2
113+
register: elb_target_group_instance
114+
115+
- name: create second target group to use ip target_type
116+
elb_target_group:
117+
name: "{{ ecs_target_group_name }}2"
118+
state: present
119+
protocol: HTTP
120+
port: 8080
121+
modify_targets: no
122+
vpc_id: '{{ setup_vpc.vpc.id }}'
123+
target_type: ip
124+
health_check_interval: 5
125+
health_check_timeout: 2
126+
healthy_threshold_count: 2
127+
unhealthy_threshold_count: 2
128+
register: elb_target_group_ip
129+
130+
- name: create load balancer
131+
elb_application_lb:
132+
name: "{{ ecs_load_balancer_name }}"
133+
state: present
134+
scheme: internal
135+
security_groups: '{{ setup_sg.group_id }}'
136+
subnets: "{{ setup_subnet.results | map(attribute='subnet.id') | list }}"
137+
listeners:
138+
- Protocol: HTTP
139+
Port: 80
140+
DefaultActions:
141+
- Type: forward
142+
TargetGroupName: "{{ ecs_target_group_name }}1"
143+
- Protocol: HTTP
144+
Port: 81
145+
DefaultActions:
146+
- Type: forward
147+
TargetGroupName: "{{ ecs_target_group_name }}2"
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# cluster "{{ ecs_cluster_name }}" is used for ecs_service tests
2+
- name: create an ECS cluster
3+
ecs_cluster:
4+
name: "{{ ecs_cluster_name }}"
5+
state: present
6+
register: ecs_cluster
7+
8+
- name: check that ecs_cluster changed
9+
assert:
10+
that:
11+
- ecs_cluster.changed
12+
13+
- name: immutable create same ECS cluster
14+
ecs_cluster:
15+
name: "{{ ecs_cluster_name }}"
16+
state: present
17+
register: ecs_cluster_again
18+
19+
- name: check that ecs_cluster did not change
20+
assert:
21+
that:
22+
- not ecs_cluster_again.changed
23+
24+
- name: create an ECS cluster to test capacity provider strategy
25+
ecs_cluster:
26+
name: "{{ ecs_cluster_name }}-cps"
27+
state: present
28+
register: ecs_cluster
29+
30+
- name: add capacity providers and strategy
31+
ecs_cluster:
32+
name: "{{ ecs_cluster_name }}-cps"
33+
state: present
34+
purge_capacity_providers: True
35+
capacity_providers:
36+
- FARGATE
37+
- FARGATE_SPOT
38+
capacity_provider_strategy:
39+
- capacity_provider: FARGATE
40+
base: 1
41+
weight: 1
42+
- capacity_provider: FARGATE_SPOT
43+
weight: 100
44+
register: ecs_cluster_update
45+
46+
- name: check that ecs_cluster was correctly updated
47+
assert:
48+
that:
49+
- ecs_cluster_update.changed
50+
- ecs_cluster_update.cluster is defined
51+
- ecs_cluster_update.cluster.capacityProviders is defined
52+
- "'FARGATE' in ecs_cluster_update.cluster.capacityProviders"
53+
54+
- name: immutable add capacity providers and strategy
55+
ecs_cluster:
56+
name: "{{ ecs_cluster_name }}-cps"
57+
state: present
58+
purge_capacity_providers: True
59+
capacity_providers:
60+
- FARGATE
61+
- FARGATE_SPOT
62+
capacity_provider_strategy:
63+
- capacity_provider: FARGATE
64+
base: 1
65+
weight: 1
66+
- capacity_provider: FARGATE_SPOT
67+
weight: 100
68+
register: ecs_cluster_update
69+
70+
- name: check that ecs_cluster was correctly updated
71+
assert:
72+
that:
73+
- not ecs_cluster_update.changed
74+
- ecs_cluster_update.cluster is defined
75+
- ecs_cluster_update.cluster.capacityProviders is defined
76+
- "'FARGATE' in ecs_cluster_update.cluster.capacityProviders"

0 commit comments

Comments
 (0)