-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Ecs scheduling strategy #4825
Ecs scheduling strategy #4825
Changes from all commits
fc1679d
7b0975d
6b5fa9e
81e7818
fdcbea6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,17 @@ func resourceAwsEcsService() *schema.Resource { | |
Default: "EC2", | ||
}, | ||
|
||
"scheduling_strategy": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, | ||
Default: ecs.SchedulingStrategyReplica, | ||
ValidateFunc: validation.StringInSlice([]string{ | ||
ecs.SchedulingStrategyDaemon, | ||
ecs.SchedulingStrategyReplica, | ||
}, false), | ||
}, | ||
|
||
"iam_role": { | ||
Type: schema.TypeString, | ||
ForceNew: true, | ||
|
@@ -321,6 +332,13 @@ func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error | |
input.LaunchType = aws.String(v.(string)) | ||
} | ||
|
||
schedulingStrategy := d.Get("scheduling_strategy").(string) | ||
input.SchedulingStrategy = aws.String(schedulingStrategy) | ||
if schedulingStrategy == ecs.SchedulingStrategyDaemon { | ||
// unset desired count if DAEMON | ||
input.DesiredCount = nil | ||
} | ||
|
||
loadBalancers := expandEcsLoadBalancers(d.Get("load_balancer").(*schema.Set).List()) | ||
if len(loadBalancers) > 0 { | ||
log.Printf("[DEBUG] Adding ECS load balancers: %s", loadBalancers) | ||
|
@@ -489,7 +507,11 @@ func resourceAwsEcsServiceRead(d *schema.ResourceData, meta interface{}) error { | |
d.Set("task_definition", taskDefinition) | ||
} | ||
|
||
d.Set("desired_count", service.DesiredCount) | ||
d.Set("scheduling_strategy", service.SchedulingStrategy) | ||
// Automatically ignore desired count if DAEMON | ||
if *service.SchedulingStrategy != ecs.SchedulingStrategyDaemon { | ||
d.Set("desired_count", service.DesiredCount) | ||
} | ||
d.Set("health_check_grace_period_seconds", service.HealthCheckGracePeriodSeconds) | ||
d.Set("launch_type", service.LaunchType) | ||
|
||
|
@@ -709,7 +731,9 @@ func resourceAwsEcsServiceUpdate(d *schema.ResourceData, meta interface{}) error | |
Cluster: aws.String(d.Get("cluster").(string)), | ||
} | ||
|
||
if d.HasChange("desired_count") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my testing, it's the number of container instances. |
||
schedulingStrategy := d.Get("scheduling_strategy").(string) | ||
// Automatically ignore desired count if DAEMON | ||
if schedulingStrategy != ecs.SchedulingStrategyDaemon && d.HasChange("desired_count") { | ||
_, n := d.GetChange("desired_count") | ||
input.DesiredCount = aws.Int64(int64(n.(int))) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,6 +103,7 @@ func TestAccAWSEcsService_withARN(t *testing.T) { | |
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo", &service), | ||
resource.TestCheckResourceAttr("aws_ecs_service.mongo", "service_registries.#", "0"), | ||
resource.TestCheckResourceAttr("aws_ecs_service.mongo", "scheduling_strategy", "REPLICA"), | ||
), | ||
}, | ||
|
||
|
@@ -111,6 +112,7 @@ func TestAccAWSEcsService_withARN(t *testing.T) { | |
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo", &service), | ||
resource.TestCheckResourceAttr("aws_ecs_service.mongo", "service_registries.#", "0"), | ||
resource.TestCheckResourceAttr("aws_ecs_service.mongo", "scheduling_strategy", "REPLICA"), | ||
), | ||
}, | ||
}, | ||
|
@@ -626,6 +628,54 @@ func TestAccAWSEcsService_withLaunchTypeEC2AndNetworkConfiguration(t *testing.T) | |
}) | ||
} | ||
|
||
func TestAccAWSEcsService_withDaemonSchedulingStrategy(t *testing.T) { | ||
var service ecs.Service | ||
rString := acctest.RandString(8) | ||
|
||
clusterName := fmt.Sprintf("tf-acc-cluster-svc-w-ss-daemon-%s", rString) | ||
tdName := fmt.Sprintf("tf-acc-td-svc-w-ss-daemon-%s", rString) | ||
svcName := fmt.Sprintf("tf-acc-svc-w-ss-daemon-%s", rString) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSEcsServiceDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSEcsServiceWithDaemonSchedulingStrategy(clusterName, tdName, svcName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost", &service), | ||
resource.TestCheckResourceAttr("aws_ecs_service.ghost", "scheduling_strategy", "DAEMON"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSEcsService_withReplicaSchedulingStrategy(t *testing.T) { | ||
var service ecs.Service | ||
rString := acctest.RandString(8) | ||
|
||
clusterName := fmt.Sprintf("tf-acc-cluster-svc-w-ss-replica-%s", rString) | ||
tdName := fmt.Sprintf("tf-acc-td-svc-w-ss-replica-%s", rString) | ||
svcName := fmt.Sprintf("tf-acc-svc-w-ss-replica-%s", rString) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSEcsServiceDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSEcsServiceWithReplicaSchedulingStrategy(clusterName, tdName, svcName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost", &service), | ||
resource.TestCheckResourceAttr("aws_ecs_service.ghost", "scheduling_strategy", "REPLICA"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSEcsService_withServiceRegistries(t *testing.T) { | ||
var service ecs.Service | ||
rString := acctest.RandString(8) | ||
|
@@ -1955,3 +2005,61 @@ resource "aws_ecs_service" "test" { | |
} | ||
`, rName, rName, rName, clusterName, tdName, svcName) | ||
} | ||
|
||
func testAccAWSEcsServiceWithDaemonSchedulingStrategy(clusterName, tdName, svcName string) string { | ||
return fmt.Sprintf(` | ||
resource "aws_ecs_cluster" "default" { | ||
name = "%s" | ||
} | ||
resource "aws_ecs_task_definition" "ghost" { | ||
family = "%s" | ||
container_definitions = <<DEFINITION | ||
[ | ||
{ | ||
"cpu": 128, | ||
"essential": true, | ||
"image": "ghost:latest", | ||
"memory": 128, | ||
"name": "ghost" | ||
} | ||
] | ||
DEFINITION | ||
} | ||
resource "aws_ecs_service" "ghost" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test resource needs to reduce the
e.g. It might also be worth noting this in the attribute documentation and/or adding a daemon example to the documentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done and added the doc/example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This acceptance test is still failing:
By changing the create function to never include
The deletion function tries to drain any
|
||
name = "%s" | ||
cluster = "${aws_ecs_cluster.default.id}" | ||
task_definition = "${aws_ecs_task_definition.ghost.family}:${aws_ecs_task_definition.ghost.revision}" | ||
scheduling_strategy = "DAEMON" | ||
deployment_maximum_percent = 100 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of requiring a special configuration for min/max, we'll setup the resource to properly ignore those configurations and differences 👍 |
||
} | ||
`, clusterName, tdName, svcName) | ||
} | ||
|
||
func testAccAWSEcsServiceWithReplicaSchedulingStrategy(clusterName, tdName, svcName string) string { | ||
return fmt.Sprintf(` | ||
resource "aws_ecs_cluster" "default" { | ||
name = "%s" | ||
} | ||
resource "aws_ecs_task_definition" "ghost" { | ||
family = "%s" | ||
container_definitions = <<DEFINITION | ||
[ | ||
{ | ||
"cpu": 128, | ||
"essential": true, | ||
"image": "ghost:latest", | ||
"memory": 128, | ||
"name": "ghost" | ||
} | ||
] | ||
DEFINITION | ||
} | ||
resource "aws_ecs_service" "ghost" { | ||
name = "%s" | ||
cluster = "${aws_ecs_cluster.default.id}" | ||
task_definition = "${aws_ecs_task_definition.ghost.family}:${aws_ecs_task_definition.ghost.revision}" | ||
scheduling_strategy = "REPLICA" | ||
desired_count = 1 | ||
} | ||
`, clusterName, tdName, svcName) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What value for
service.DesiredCount
gets returned when inDAEMON
mode? Is it0
or the number of container instances? We should generally try to calld.Set()
if possible.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my testing, it's the number of container instances, which can change periodically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the following
DiffSuppressFunc
to thedesired_count
,deployment_minimum_percent
, anddeployment_maximum_percent
attributes, we can continue to always calld.Set("desired_count", service.DesiredCount)
(along with the others) and remove the conditional in the read function. This will remove the breaking change for outputs that depend on thedesired_count
attribute always existing.