From e06f32ffe94c04150de212f55df21187ac72094c Mon Sep 17 00:00:00 2001 From: Greg Thole Date: Tue, 17 Jan 2017 13:10:45 -0500 Subject: [PATCH] Provider AWS: Add Placement Strategy to aws_ecs_service resource (#11201) * Add aws_ecs_service placement_strategy param * Update docs --- .../providers/aws/resource_aws_ecs_service.go | 52 +++++++++++++++++ .../aws/resource_aws_ecs_service_test.go | 56 +++++++++++++++++++ .../providers/aws/r/ecs_service.html.markdown | 9 +++ 3 files changed, 117 insertions(+) diff --git a/builtin/providers/aws/resource_aws_ecs_service.go b/builtin/providers/aws/resource_aws_ecs_service.go index 4e40376a3..b8b2168e1 100644 --- a/builtin/providers/aws/resource_aws_ecs_service.go +++ b/builtin/providers/aws/resource_aws_ecs_service.go @@ -101,6 +101,27 @@ func resourceAwsEcsService() *schema.Resource { }, Set: resourceAwsEcsLoadBalancerHash, }, + + "placement_strategy": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + MaxItems: 5, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + "field": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + }, + }, + }, }, } } @@ -132,6 +153,19 @@ func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error input.Role = aws.String(v.(string)) } + strategies := d.Get("placement_strategy").(*schema.Set).List() + if len(strategies) > 0 { + var ps []*ecs.PlacementStrategy + for _, raw := range strategies { + p := raw.(map[string]interface{}) + ps = append(ps, &ecs.PlacementStrategy{ + Type: aws.String(p["type"].(string)), + Field: aws.String(p["field"].(string)), + }) + } + input.PlacementStrategy = ps + } + log.Printf("[DEBUG] Creating ECS service: %s", input) // Retry due to AWS IAM policy eventual consistency @@ -240,9 +274,27 @@ func resourceAwsEcsServiceRead(d *schema.ResourceData, meta interface{}) error { d.Set("load_balancers", flattenEcsLoadBalancers(service.LoadBalancers)) } + if err := d.Set("placement_strategy", flattenPlacementStrategy(service.PlacementStrategy)); err != nil { + log.Printf("[ERR] Error setting placement_strategy for (%s): %s", d.Id(), err) + } + return nil } +func flattenPlacementStrategy(pss []*ecs.PlacementStrategy) []map[string]interface{} { + if len(pss) == 0 { + return nil + } + results := make([]map[string]interface{}, 0) + for _, ps := range pss { + c := make(map[string]interface{}) + c["type"] = *ps.Type + c["field"] = *ps.Field + results = append(results, c) + } + return results +} + func resourceAwsEcsServiceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ecsconn diff --git a/builtin/providers/aws/resource_aws_ecs_service_test.go b/builtin/providers/aws/resource_aws_ecs_service_test.go index 62e50e980..3f3fd6f60 100644 --- a/builtin/providers/aws/resource_aws_ecs_service_test.go +++ b/builtin/providers/aws/resource_aws_ecs_service_test.go @@ -257,6 +257,30 @@ func TestAccAWSEcsService_withAlb(t *testing.T) { }) } +func TestAccAWSEcsServiceWithPlacementStrategy(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEcsServiceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSEcsService, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), + resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_strategy.#", "0"), + ), + }, + resource.TestStep{ + Config: testAccAWSEcsServiceWithPlacementStrategy, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), + resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_strategy.#", "1"), + ), + }, + }, + }) +} + func testAccCheckAWSEcsServiceDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ecsconn @@ -360,6 +384,38 @@ resource "aws_ecs_service" "mongo" { } ` +var testAccAWSEcsServiceWithPlacementStrategy = ` +resource "aws_ecs_cluster" "default" { + name = "terraformecstest1" +} + +resource "aws_ecs_task_definition" "mongo" { + family = "mongodb" + container_definitions = < **Note:** As a result of an AWS limitation, a single `load_balancer` can be attached to the ECS service at most. See [related docs](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html#load-balancing-concepts).