-
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
r/aws_globalaccelerator_endpoint_group: Add aws_globalaccelerator_endpoint_group resource #8328
r/aws_globalaccelerator_endpoint_group: Add aws_globalaccelerator_endpoint_group resource #8328
Conversation
…point_group resource
…vider-aws into f-globalaccelerator-endpoint-group
I'll look at these build failure shortly. Sorry about that. |
…vider-aws into f-globalaccelerator-endpoint-group
476ba71
to
b367746
Compare
@bflad This is all ready to go. Let me know if I can do anything |
Anyway to get senpai to notice this? |
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.
Hi @john-delivuk 👋 Thanks for rebasing the original pull request. See the below for some initial feedback items. Please reach out if you have any questions or do not have time to implement them.
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Timeouts: &schema.ResourceTimeout{ |
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.
These customizable timeouts seem extraneous as the timeout is not based on a scalable dimension (such as data size). I would suggest removing this schema declaration and replace d.Timeout(schema.TimeoutXXX)
usage with the time duration. If operations take longer than the hardcoded defaults, we should increase them for everyone. 😄
}, | ||
"endpoint_group_region": { | ||
Type: schema.TypeString, | ||
Required: true, |
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.
This attribute seems like it should default to the provider region rather than requiring configuration. 👍
Required: true, | |
Optional: true, | |
Computed: true, |
In the code below:
region := meta.(*AWSClient).region
// ...
EndpointGroupRegion: aws.String(region),
// ...
if v, ok := d.GetOk("endpoint_group_region"); ok {
opts.EndpointGroupRegion = aws.String(v.(string))
}
"health_check_interval_seconds": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Computed: true, |
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.
This attribute appears to have a default (which should be used for drift detection) and validation information in the Global Accelerator API Reference:
Computed: true, | |
Default: 30, | |
ValidateFunc: validation.IntBetween(10, 30), |
"health_check_path": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, |
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.
This attribute appears to have a default in the Global Accelerator API Reference, which should be used to perform drift detection:
Computed: true, | |
Default: "/", |
Computed: true, | ||
}, | ||
"endpoint_configurations": { | ||
Type: schema.TypeList, |
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.
Does the API guarantee ordering of this attribute in its responses? If not, this should be switched to schema.TypeSet
return err | ||
} | ||
|
||
// Creating an endpoint group triggers the accelerator to change status to InPending |
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.
This logic should reuse the available function (albeit slightly poor naming): resourceAwsGlobalAcceleratorAcceleratorWaitForState
err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)
if err != nil {
return err
}
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.
Removing this duplicate logic on merge.
return err | ||
} | ||
|
||
// Creating an endpoint group triggers the accelerator to change status to InPending |
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.
This logic should reuse the available function (albeit slightly poor naming): resourceAwsGlobalAcceleratorAcceleratorWaitForState
err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)
if err != nil {
return err
}
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.
Removing this duplicate logic on merge.
return err | ||
} | ||
|
||
// Deleting an endpoint group triggers the accelerator to change status to InPending |
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.
This logic should reuse the available function (albeit slightly poor naming): resourceAwsGlobalAcceleratorAcceleratorWaitForState
err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)
if err != nil {
return err
}
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.
Removing this duplicate logic on merge.
d.Set("health_check_protocol", endpointGroup.HealthCheckProtocol) | ||
d.Set("threshold_count", endpointGroup.ThresholdCount) | ||
d.Set("traffic_dial_percentage", endpointGroup.TrafficDialPercentage) | ||
d.Set("endpoint_configurations", resourceAwsGlobalAcceleratorEndpointGroupFlattenEndpointDescriptions(endpointGroup.EndpointDescriptions)) |
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.
When using d.Set()
with aggregate types (TypeList, TypeSet, TypeMap), we should perform error checking to prevent issues where the code is not properly able to set the Terraform state. e.g.
d.Set("endpoint_configurations", resourceAwsGlobalAcceleratorEndpointGroupFlattenEndpointDescriptions(endpointGroup.EndpointDescriptions)) | |
if err := d.Set("endpoint_configurations", resourceAwsGlobalAcceleratorEndpointGroupFlattenEndpointDescriptions(endpointGroup.EndpointDescriptions)); err != nil { | |
return fmt.Errorf("error setting endpoint_configurations: %s", err) | |
} |
Hey @bflad Didn't expect this much feedback, just give me about 2 weeks and I'll put this together to the best of my ability. |
I lied, I got most of this taken care of last night. I'll try to update the PR today. |
Sorry for the delay, please review the docs throughly, I went through this a few times, but I'm sure I overlooked something. Thanks @bflad |
Do we yet know by when this be released? |
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.
Hi @john-delivuk 👋 Thanks for the updates. I left some final review items below, but this is otherwise in pretty good shape. Please reach out if you have any questions or do not have time to implement the feedback.
website/aws.erb
Outdated
@@ -1486,6 +1486,11 @@ | |||
<a href="/docs/providers/aws/r/globalaccelerator_accelerator.html">aws_globalaccelerator_accelerator</a> | |||
</li> | |||
</ul> | |||
<ul class="nav"> | |||
<li> | |||
<a href="/docs/providers/aws/r/globalaccelerator_endpoint_group.html">globalaccelerator_endpoint_group</a> |
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.
<a href="/docs/providers/aws/r/globalaccelerator_endpoint_group.html">globalaccelerator_endpoint_group</a> | |
<a href="/docs/providers/aws/r/globalaccelerator_endpoint_group.html">aws_globalaccelerator_endpoint_group</a> |
|
||
acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id()) | ||
if err != nil { | ||
err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn) |
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.
Sorry if my original comment was unclear. This waiter should exist outside this error conditional and replace the duplicated StateChangeConf
logic below. e.g.
acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())
if err != nil {
return err
}
err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)
if err != nil {
return err
}
return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)
for i, configuration := range configurations { | ||
m := make(map[string]interface{}) | ||
|
||
m["endpoint_id"] = *configuration.EndpointId |
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.
To prevent potential panics, this should use the AWS Go SDK provided conversion function:
m["endpoint_id"] = *configuration.EndpointId | |
m["endpoint_id"] = aws.StringValue(configuration.EndpointId) |
m := make(map[string]interface{}) | ||
|
||
m["endpoint_id"] = *configuration.EndpointId | ||
m["weight"] = *configuration.Weight |
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.
To prevent potential panics, this should use the AWS Go SDK provided conversion function:
m["weight"] = *configuration.Weight | |
m["weight"] = aws.Int64Value(configuration.Weight) |
|
||
acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id()) | ||
if err != nil { | ||
err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn) |
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.
Same here -- sorry if my original comment was unclear. This waiter should exist outside this error conditional and replace the duplicated StateChangeConf
logic below. e.g.
acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())
if err != nil {
return err
}
err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)
if err != nil {
return err
}
return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)
|
||
```hcl | ||
resource "globalaccelerator_endpoint_group" "example" { | ||
listener_arn = "arn:aws:globalaccelerator::123456789012:accelerator/1234abcd-abcd-1234-abcd-1234abcdefgh/listener/0123vxyz" |
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.
Examples should prefer to use resource references where possible to illustrate real world usage, e.g.
listener_arn = "arn:aws:globalaccelerator::123456789012:accelerator/1234abcd-abcd-1234-abcd-1234abcdefgh/listener/0123vxyz" | |
listener_arn = "${aws_globalaccelerator_listener.example.id}" |
resource "globalaccelerator_endpoint_group" "example" { | ||
listener_arn = "arn:aws:globalaccelerator::123456789012:accelerator/1234abcd-abcd-1234-abcd-1234abcdefgh/listener/0123vxyz" | ||
endpoint_configuration { | ||
EndpointId = "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" |
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.
The argument name here is endpoint_id
. Also, same here where examples should prefer to use resource references where possible to illustrate real world usage, e.g.
EndpointId = "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" | |
endpoint_id = "${aws_lb.example.arn}" |
listener_arn = "arn:aws:globalaccelerator::123456789012:accelerator/1234abcd-abcd-1234-abcd-1234abcdefgh/listener/0123vxyz" | ||
endpoint_configuration { | ||
EndpointId = "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" | ||
Weight = "100" |
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.
The argument name here is lowercase weight
and is an integer which does not need to be wrapped in quotes:
Weight = "100" | |
weight = 100 |
|
||
**endpoint_configuration** supports the following attributes: | ||
|
||
* `EndpointId` - (Optional) An ID for the endpoint. If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource. If the endpoint is an Elastic IP address, this is the Elastic IP address allocation ID. |
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.
* `EndpointId` - (Optional) An ID for the endpoint. If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource. If the endpoint is an Elastic IP address, this is the Elastic IP address allocation ID. | |
* `endpoint_id` - (Optional) An ID for the endpoint. If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource. If the endpoint is an Elastic IP address, this is the Elastic IP address allocation ID. |
**endpoint_configuration** supports the following attributes: | ||
|
||
* `EndpointId` - (Optional) An ID for the endpoint. If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource. If the endpoint is an Elastic IP address, this is the Elastic IP address allocation ID. | ||
* `Weight` - (Optional) The weight associated with the endpoint. When you add weights to endpoints, you configure AWS Global Accelerator to route traffic based on proportions that you specify. |
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.
* `Weight` - (Optional) The weight associated with the endpoint. When you add weights to endpoints, you configure AWS Global Accelerator to route traffic based on proportions that you specify. | |
* `weight` - (Optional) The weight associated with the endpoint. When you add weights to endpoints, you configure AWS Global Accelerator to route traffic based on proportions that you specify. |
@bflad Thanks for the feedback, everything is updated according to your notes. Let me know if there is anything else required. |
…vider-aws into f-globalaccelerator-endpoint-group
For my own knowledge, should I mark resolved, or should I let the reviewer :) |
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.
Thanks for the updates, @john-delivuk. Performed some final adjustments in a followup commit to get the acceptance testing fully passing (noted below) and this is good to go. Great work. 🚀
Output from acceptance testing:
--- PASS: TestAccAwsGlobalAcceleratorEndpointGroup_basic (258.79s)
--- PASS: TestAccAwsGlobalAcceleratorEndpointGroup_update (316.32s)
"traffic_dial_percentage": { | ||
Type: schema.TypeFloat, | ||
Optional: true, | ||
Default: 100, |
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.
When running the acceptance testing, this Default
and ValidateFunc
were causing the below failure:
--- FAIL: TestAccAwsGlobalAcceleratorEndpointGroup_basic (1.79s)
testing.go:568: Step 0 error: config is invalid: expected type of traffic_dial_percentage to be int
--- FAIL: TestAccAwsGlobalAcceleratorEndpointGroup_update (1.79s)
testing.go:568: Step 0 error: config is invalid: expected type of traffic_dial_percentage to be int
The fix here is to switch them to Default: 100.0
and ValidateFunc: validation.FloatBetween(0.0, 100.0)
to match Type: schema.TypeFloat
👍
} | ||
|
||
if v, ok := d.GetOk("endpoint_configuration"); ok { | ||
opts.EndpointConfigurations = resourceAwsGlobalAcceleratorEndpointGroupExpandEndpointConfigurations(v.([]interface{})) |
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.
When running the acceptance testing, the type assertion here caused a panic:
panic: interface conversion: interface {} is *schema.Set, not []interface {}
goroutine 1169 [running]:
github.com/terraform-providers/terraform-provider-aws/aws.resourceAwsGlobalAcceleratorEndpointGroupCreate(0xc0013ed8f0, 0x5238f40, 0xc00008fc00, 0x2, 0xaa129c0)
/Users/bflad/src/github.com/terraform-providers/terraform-provider-aws/aws/resource_aws_globalaccelerator_endpoint_group.go:136 +0xbb1
The fix here is to use v.(*schema.Set).List()
for converting the Type: schema.TypeSet
attribute into a []interface()
for the function call. Same update needed in the Update
function.
return err | ||
} | ||
|
||
// Creating an endpoint group triggers the accelerator to change status to InPending |
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.
Removing this duplicate logic on merge.
return err | ||
} | ||
|
||
// Creating an endpoint group triggers the accelerator to change status to InPending |
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.
Removing this duplicate logic on merge.
return err | ||
} | ||
|
||
// Deleting an endpoint group triggers the accelerator to change status to InPending |
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.
Removing this duplicate logic on merge.
@@ -0,0 +1,55 @@ | |||
--- | |||
layout: "aws" | |||
page_title: "AWS: globalaaws_globalaccelerator_endpoint_groupccelerator_endpoint_group" |
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.
Fixing on merge: page_title: "AWS: aws_globalaccelerator_endpoint_group"
|
||
Provides a Global Accelerator endpoint group. | ||
|
||
## Attributes Reference |
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.
Fixing on merge.
resource.TestCheckResourceAttr(resourceName, "threshold_count", "3"), | ||
resource.TestCheckResourceAttr(resourceName, "traffic_dial_percentage", "100"), | ||
resource.TestCheckResourceAttr(resourceName, "endpoint_configuration.#", "1"), | ||
resource.TestCheckResourceAttr(resourceName, "endpoint_configuration.0.weight", "10"), |
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.
Since the endpoint_configuration
attribute is Type: schema.TypeSet
, the .0.
index in the state needs to instead be calculated from the Set
function for the attribute (if Set
is undefined for a TypeSet
attribute, it falls back to an automatically calculated value from the underlying types):
--- FAIL: TestAccAwsGlobalAcceleratorEndpointGroup_basic (252.96s)
testing.go:568: Step 0 error: Check failed: Check 9/9 error: aws_globalaccelerator_endpoint_group.example: Attribute 'endpoint_configuration.0.weight' not found
Since the endpoint_id
value is dynamic, the index hash value in turn is dynamic as well and this type of state checking in the acceptance testing is problematic.
If the resource supports import, the ImportStateVerify: true
testing will automatically ensures all state values match after Terraform refresh into an empty state (e.g. the values returned by just Read
function itself), so this problematic TestCheckResourceAttr()
can typically be removed fairly safely in that scenario.
Config: testAccGlobalAcceleratorEndpointGroup_update(rInt), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckGlobalAcceleratorEndpointGroupExists(resourceName), | ||
resource.TestCheckResourceAttr(resourceName, "health_check_interval_seconds", "10"), |
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.
It seems like the API needs at least one endpoint configuration for health check updates to actually occur (tried injecting a one minute delay between the update and read to no avail):
--- FAIL: TestAccAwsGlobalAcceleratorEndpointGroup_update (289.47s)
testing.go:568: Step 1 error: Check failed: Check 2/8 error: aws_globalaccelerator_endpoint_group.example: Attribute 'health_check_interval_seconds' expected "10", got "30"
Opted to keep an endpoint configuration in the second configuration for now so the testing properly passes.
final feedback Reference: hashicorp#8328 Output from acceptance testing: ``` --- PASS: TestAccAwsGlobalAcceleratorEndpointGroup_basic (258.79s) --- PASS: TestAccAwsGlobalAcceleratorEndpointGroup_update (316.32s) ```
Thanks @john-delivuk and @bflad for landing support for Global Accelerator!! 🎉 |
This has been released in version 2.16.0 of the Terraform AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks! |
Rebase of PR #7005
Partly addresses #6739
Changes proposed in this pull request:
aws_globalaccelerator_endpoint_group
Output from acceptance testing: