Skip to content

Commit

Permalink
resource/aws_instance: Add check for empty credit_specification block (
Browse files Browse the repository at this point in the history
…#9003)

Fixes: #6532

When given an empty credit_specification block (i.e cpu_credits is missing) the Terraform provider
will crash upon trying to type assert on the empty (nil) block. This check introduces a guard clause around the type assertion
to protect around the empty (nil) block. A warning is logged to indicated that a default value will be used in place of the missing
value.

Acceptance tests after changes
```
--- PASS: TestAccAWSInstance_creditSpecification_unknownCpuCredits_t2
--- PASS: TestAccAWSInstance_creditSpecification_unknownCpuCredits_t3
```
  • Loading branch information
nywilken authored Jun 20, 2019
1 parent b73b691 commit b6d0c83
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
9 changes: 6 additions & 3 deletions aws/resource_aws_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -1764,9 +1764,12 @@ func buildAwsInstanceOpts(
if v, ok := d.GetOk("credit_specification"); ok {
// Only T2 and T3 are burstable performance instance types and supports Unlimited
if strings.HasPrefix(instanceType, "t2") || strings.HasPrefix(instanceType, "t3") {
cs := v.([]interface{})[0].(map[string]interface{})
opts.CreditSpecification = &ec2.CreditSpecificationRequest{
CpuCredits: aws.String(cs["cpu_credits"].(string)),
if cs, ok := v.([]interface{})[0].(map[string]interface{}); ok {
opts.CreditSpecification = &ec2.CreditSpecificationRequest{
CpuCredits: aws.String(cs["cpu_credits"].(string)),
}
} else {
log.Print("[WARN] credit_specification is defined but the value of cpu_credits is missing, default value will be used.")
}
} else {
log.Print("[WARN] credit_specification is defined but instance type is not T2/T3. Ignoring...")
Expand Down
72 changes: 72 additions & 0 deletions aws/resource_aws_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,50 @@ func TestAccAWSInstance_creditSpecification_unlimitedCpuCredits(t *testing.T) {
})
}

func TestAccAWSInstance_creditSpecification_unknownCpuCredits_t2(t *testing.T) {
var instance ec2.Instance
rInt := acctest.RandInt()
resName := "aws_instance.foo"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceConfig_creditSpecification_unknownCpuCredits(rInt, "t2.micro"),
Check: resource.ComposeTestCheckFunc(
testAccCheckInstanceExists(resName, &instance),
resource.TestCheckResourceAttr(resName, "credit_specification.#", "1"),
resource.TestCheckResourceAttr(resName, "credit_specification.0.cpu_credits", "standard"),
),
},
},
})
}

func TestAccAWSInstance_creditSpecification_unknownCpuCredits_t3(t *testing.T) {
var instance ec2.Instance
rInt := acctest.RandInt()
resName := "aws_instance.foo"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceConfig_creditSpecification_unknownCpuCredits(rInt, "t3.micro"),
Check: resource.ComposeTestCheckFunc(
testAccCheckInstanceExists(resName, &instance),
resource.TestCheckResourceAttr(resName, "credit_specification.#", "1"),
resource.TestCheckResourceAttr(resName, "credit_specification.0.cpu_credits", "unlimited"),
),
},
},
})
}

func TestAccAWSInstance_creditSpecification_updateCpuCredits(t *testing.T) {
var first, second, third ec2.Instance
resName := "aws_instance.foo"
Expand Down Expand Up @@ -3827,6 +3871,7 @@ resource "aws_instance" "foo" {
ami = "ami-51537029" # us-west-2
instance_type = "t3.micro"
subnet_id = "${aws_subnet.my_subnet.id}"
}
`, rInt)
}
Expand Down Expand Up @@ -3971,6 +4016,33 @@ resource "aws_instance" "foo" {
`, rInt)
}

func testAccInstanceConfig_creditSpecification_unknownCpuCredits(rInt int, instanceType string) string {
return fmt.Sprintf(`
resource "aws_vpc" "my_vpc" {
cidr_block = "172.16.0.0/16"
tags = {
Name = "tf-acctest-%d"
}
}
resource "aws_subnet" "my_subnet" {
vpc_id = "${aws_vpc.my_vpc.id}"
cidr_block = "172.16.20.0/24"
availability_zone = "us-west-2a"
}
resource "aws_instance" "foo" {
ami = "ami-51537029" # us-west-2
instance_type = %q
subnet_id = "${aws_subnet.my_subnet.id}"
credit_specification {
}
}
`, rInt, instanceType)
}

func testAccInstanceConfig_UserData_Base(rInt int) string {
return fmt.Sprintf(`
data "aws_ami" "amzn-ami-minimal-hvm-ebs" {
Expand Down

0 comments on commit b6d0c83

Please sign in to comment.