From 9d4a689d8d55ccf11bc6691b9ab95bd38e8dfd2d Mon Sep 17 00:00:00 2001 From: ysfj Date: Thu, 21 Feb 2019 21:48:10 +0000 Subject: [PATCH 1/4] add partition_count argument to aws_placement_group AWS added partition placement group feature which uses partition_count argument. So I added partiton_count argument to set the number. --- aws/resource_aws_placement_group.go | 20 +++++++++++ aws/resource_aws_placement_group_test.go | 37 ++++++++++++++++++++ website/docs/r/placement_group.html.markdown | 1 + 3 files changed, 58 insertions(+) diff --git a/aws/resource_aws_placement_group.go b/aws/resource_aws_placement_group.go index 58b579b8004..51cd18a22db 100644 --- a/aws/resource_aws_placement_group.go +++ b/aws/resource_aws_placement_group.go @@ -32,6 +32,12 @@ func resourceAwsPlacementGroup() *schema.Resource { Required: true, ForceNew: true, }, + "partition_count": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + }, }, } } @@ -44,6 +50,17 @@ func resourceAwsPlacementGroupCreate(d *schema.ResourceData, meta interface{}) e GroupName: aws.String(name), Strategy: aws.String(d.Get("strategy").(string)), } + + // PartitionCount is only valid for strategy partition. + strategy := d.Get("strategy").(string) + partition_count := d.Get("partition_count").(int) + + if strategy != "partition" && partition_count > 1 { + log.Printf("[WARN] partition_count is only valid for storategy partition for PlacementGroup") + } else if strategy == "partition" { + input.PartitionCount = aws.Int64(int64(partition_count)) + } + log.Printf("[DEBUG] Creating EC2 Placement group: %s", input) _, err := conn.CreatePlacementGroup(&input) if err != nil { @@ -100,6 +117,9 @@ func resourceAwsPlacementGroupRead(d *schema.ResourceData, meta interface{}) err d.Set("name", pg.GroupName) d.Set("strategy", pg.Strategy) + if pg.PartitionCount != nil { + d.Set("partition_count", pg.PartitionCount) + } return nil } diff --git a/aws/resource_aws_placement_group_test.go b/aws/resource_aws_placement_group_test.go index d670f875e1c..ea3c765e1cb 100644 --- a/aws/resource_aws_placement_group_test.go +++ b/aws/resource_aws_placement_group_test.go @@ -86,6 +86,33 @@ func testAccCheckAWSPlacementGroupExists(n string) resource.TestCheckFunc { } } +func TestAccAWSPlacementGroup_partition(t *testing.T) { + resourceName := "aws_placement_group.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSPlacementGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSPlacementGroupConfig_partition(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSPlacementGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "strategy", "partition"), + resource.TestCheckResourceAttr(resourceName, "partition_count", "7"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccAWSPlacementGroupConfig(rName string) string { return fmt.Sprintf(` resource "aws_placement_group" "test" { @@ -94,3 +121,13 @@ resource "aws_placement_group" "test" { } `, rName) } + +func testAccAWSPlacementGroupConfig_partition(rName string) string { + return fmt.Sprintf(` +resource "aws_placement_group" "test" { + name = %q + strategy = "partition" + partition_count = 7 +} +`, rName) +} diff --git a/website/docs/r/placement_group.html.markdown b/website/docs/r/placement_group.html.markdown index 0c659f5f679..1ebedd641dc 100644 --- a/website/docs/r/placement_group.html.markdown +++ b/website/docs/r/placement_group.html.markdown @@ -26,6 +26,7 @@ The following arguments are supported: * `name` - (Required) The name of the placement group. * `strategy` - (Required) The placement strategy. +* `partition_count` - (Optional) The number of partitions. Valid only when Strategy is set to partition. ## Attributes Reference From c211349fc7a7396392193651ac55146f294f8b8b Mon Sep 17 00:00:00 2001 From: Cako Date: Thu, 28 Feb 2019 12:34:37 -0700 Subject: [PATCH 2/4] add partition number support --- aws/resource_aws_instance.go | 16 ++++++++++++++++ aws/resource_aws_instance_test.go | 17 ++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_instance.go b/aws/resource_aws_instance.go index a66e5d53b6f..fd944346d5a 100644 --- a/aws/resource_aws_instance.go +++ b/aws/resource_aws_instance.go @@ -73,6 +73,13 @@ func resourceAwsInstance() *schema.Resource { ForceNew: true, }, + "placement_partition_number": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + }, + "instance_type": { Type: schema.TypeString, Required: true, @@ -710,6 +717,9 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { if instance.Placement.GroupName != nil { d.Set("placement_group", instance.Placement.GroupName) } + if instance.Placement.PartitionNumber != nil { + d.Set("placement_partition_number", instance.Placement.PartitionNumber) + } if instance.Placement.Tenancy != nil { d.Set("tenancy", instance.Placement.Tenancy) } @@ -1811,6 +1821,8 @@ func buildAwsInstanceOpts( subnet, hasSubnet := d.GetOk("subnet_id") subnetID := subnet.(string) + partitionNumber, hasPartitionNumber := d.GetOk("placement_partition_number") + // Placement is used for aws_instance; SpotPlacement is used for // aws_spot_instance_request. They represent the same data. :-| opts.Placement = &ec2.Placement{ @@ -1818,6 +1830,10 @@ func buildAwsInstanceOpts( GroupName: aws.String(d.Get("placement_group").(string)), } + if hasPartitionNumber { + opts.Placement.PartitionNumber = aws.Int64(int64(partitionNumber.(int))) + } + opts.SpotPlacement = &ec2.SpotPlacement{ AvailabilityZone: aws.String(d.Get("availability_zone").(string)), GroupName: aws.String(d.Get("placement_group").(string)), diff --git a/aws/resource_aws_instance_test.go b/aws/resource_aws_instance_test.go index 4f23f0b9666..9bcc037cc0b 100644 --- a/aws/resource_aws_instance_test.go +++ b/aws/resource_aws_instance_test.go @@ -767,6 +767,7 @@ func TestAccAWSInstance_vpc(t *testing.T) { func TestAccAWSInstance_placementGroup(t *testing.T) { var v ec2.Instance rStr := acctest.RandString(5) + rInt := acctest.RandIntRange(1, 3) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -776,7 +777,7 @@ func TestAccAWSInstance_placementGroup(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfigPlacementGroup(rStr), + Config: testAccInstanceConfigPlacementGroup(rStr, rInt), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists( "aws_instance.foo", &v), @@ -784,6 +785,10 @@ func TestAccAWSInstance_placementGroup(t *testing.T) { "aws_instance.foo", "placement_group", fmt.Sprintf("testAccInstanceConfigPlacementGroup_%s", rStr)), + resource.TestCheckResourceAttr( + "aws_instance.foo", + "placement_partition_number", + fmt.Sprintf("%d", rInt)), ), }, }, @@ -2565,7 +2570,7 @@ resource "aws_instance" "foo" { } ` -func testAccInstanceConfigPlacementGroup(rStr string) string { +func testAccInstanceConfigPlacementGroup(rStr string, rInt int) string { return fmt.Sprintf(` resource "aws_vpc" "foo" { cidr_block = "10.1.0.0/16" @@ -2584,7 +2589,8 @@ resource "aws_subnet" "foo" { resource "aws_placement_group" "foo" { name = "testAccInstanceConfigPlacementGroup_%s" - strategy = "cluster" + strategy = "partition" + partition_count = 3 } # Limitations: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html#concepts-placement-groups @@ -2594,11 +2600,12 @@ resource "aws_instance" "foo" { instance_type = "c3.large" subnet_id = "${aws_subnet.foo.id}" associate_public_ip_address = true - placement_group = "${aws_placement_group.foo.name}" + placement_group = "${aws_placement_group.foo.name}" + placement_partition_number = %d # pre-encoded base64 data user_data = "3dc39dda39be1205215e776bad998da361a5955d" } -`, rStr) +`, rStr, rInt) } const testAccInstanceConfigIpv6ErrorConfig = ` From 9b300a1e0e4af3c8b1e2405a7197f7ebe2f443d2 Mon Sep 17 00:00:00 2001 From: David Cako Date: Thu, 28 Feb 2019 12:47:35 -0700 Subject: [PATCH 3/4] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb3af2b3012..983486b8594 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## placement_groups + +Implements `placement_partition_number` on top of ysfj's partition_count +enhancement (https://github.com/david-cako/terraform-provider-aws/commit/9d4a689d8d55ccf11bc6691b9ab95bd38e8dfd2d) + ## 1.60.0 (Unreleased) ENHANCEMENTS: From 60d942f80a5b17ae53f3a021a7b1a68c70eba96b Mon Sep 17 00:00:00 2001 From: David Cako Date: Thu, 28 Feb 2019 18:32:05 -0700 Subject: [PATCH 4/4] fix unit test --- aws/resource_aws_instance_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_instance_test.go b/aws/resource_aws_instance_test.go index 9bcc037cc0b..e1925633790 100644 --- a/aws/resource_aws_instance_test.go +++ b/aws/resource_aws_instance_test.go @@ -767,7 +767,7 @@ func TestAccAWSInstance_vpc(t *testing.T) { func TestAccAWSInstance_placementGroup(t *testing.T) { var v ec2.Instance rStr := acctest.RandString(5) - rInt := acctest.RandIntRange(1, 3) + rInt := 3 resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -2580,7 +2580,8 @@ resource "aws_vpc" "foo" { } resource "aws_subnet" "foo" { - cidr_block = "10.1.1.0/24" + cidr_block = "10.1.1.0/24" + availability_zone = "us-west-2a" vpc_id = "${aws_vpc.foo.id}" tags = { Name = "tf-acc-instance-placement-group" @@ -2596,8 +2597,8 @@ resource "aws_placement_group" "foo" { # Limitations: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html#concepts-placement-groups resource "aws_instance" "foo" { # us-west-2 - ami = "ami-55a7ea65" - instance_type = "c3.large" + ami = "ami-01e24be29428c15b2" + instance_type = "t2.micro" subnet_id = "${aws_subnet.foo.id}" associate_public_ip_address = true placement_group = "${aws_placement_group.foo.name}"