-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
New Resource: aws_sagemaker_endpoint_configuration #2477
New Resource: aws_sagemaker_endpoint_configuration #2477
Conversation
a74dcc4
to
e15e614
Compare
3d5897f
to
67d1a8f
Compare
1c4f357
to
81ec6a4
Compare
81ec6a4
to
f74eae4
Compare
e7d5764
to
df51483
Compare
df51483
to
1043e89
Compare
1043e89
to
04709d4
Compare
04709d4
to
a496c39
Compare
a496c39
to
782eb14
Compare
782eb14
to
6f318ea
Compare
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.
Hello again @jckuester! Things were fairly similar between this review and the model review but again things are looking good.
}, | ||
|
||
"production_variants": { | ||
Type: schema.TypeSet, |
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.
Is there a reason this is a TypeSet? If it's because this comes back from the api unordered then this is perfect to use. Otherwise we should use a TypeList as they are easier to access and use because of it's ordered nature.
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.
Done.
ForceNew: true, | ||
}, | ||
|
||
"creation_time": { |
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.
Is there a need for this attribute. I don't think it adds a ton of value inside of Terraform and can be removed.
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.
Done.
} | ||
|
||
d.SetId(name) | ||
if err := d.Set("arn", resp.EndpointConfigArn); err != nil { |
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 this is set in the read, I think we can remove it from here
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.
Done.
result := make([]map[string]interface{}, 0, len(list)) | ||
for _, i := range list { | ||
l := map[string]interface{}{ | ||
"variant_name": *i.VariantName, |
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.
We should check that these aren't nil before setting them
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.
Done.
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckSagemakerEndpointConfigExists("aws_sagemaker_endpoint_configuration.foo", | ||
&endpointConfig), | ||
testAccCheckSagemakerEndpointConfigName(&endpointConfig, |
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.
I'm not sure we need these types of checks as it's the same as what you're checking below since the state is using the same object you're referencing here.
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.
Done.
* `model_name` - (Required) The name of the model to use. | ||
* `initial_instance_count` - (Required) Initial number of instances used for auto-scaling. | ||
* `instance_type` (Required) - The type of instance to start. | ||
* `initial_variant_weight` - (Required) |
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.
We should add a brief description here
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.
Done.
variant_name = "variant-1" | ||
model_name = "my-model" | ||
initial_instance_count = 1 | ||
instance_type = "" |
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.
Can instance_type
be ""
? We should populate this with a valid value
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.
Done.
6f318ea
to
b4efa5a
Compare
ebfa00a
to
5172ec3
Compare
5172ec3
to
20cff99
Compare
20cff99
to
694c1c2
Compare
694c1c2
to
3326c92
Compare
3326c92
to
077f20d
Compare
How can we help to get this merged? |
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 @jckuester 👋 Thanks so much for this contribution. I'll be working through the rest of these resource reviews the coming week(s) as a high priority so we can finally get all these shipped. 🚢
A few more minor little things below, but otherwise looks pretty good! Please reach out with any questions or if you do not have time to implement the feedback here.
} | ||
|
||
if sagemakerErr.Code() == "ResourceNotFound" { | ||
return resource.RetryableError(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.
Is there a particular reason to retry for 5 minutes for the the ResourceNotFound
error? Seems like something we where we would want to exit successfully. 😄
If there's no reason to retry things here I would remove the resource.Retry()
logic altogether and just simplify the deletion to:
func resourceAwsSagemakerEndpointConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).sagemakerconn
deleteOpts := &sagemaker.DeleteEndpointConfigInput{
EndpointConfigName: aws.String(d.Id()),
}
log.Printf("[INFO] Deleting Sagemaker endpoint configuration: %s", d.Id())
_, err := conn.DeleteEndpointConfig(deleteOpts)
if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "") {
return nil
}
if err != nil {
return fmt.Errorf("error deleting SageMaker Endpoint Configuration (%s): %s", d.Id(), err)
}
return nil
}
func resourceAwsSagemakerEndpointConfigurationUpdate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).sagemakerconn | ||
|
||
d.Partial(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.
Nit: Since this resource does not require partial Terraform state updates, we should remove the usage of d.Partial()
and d.SetPartial()
}) | ||
} | ||
|
||
func expandProductionVariants(configured []interface{}) ([]*sagemaker.ProductionVariant, error) { |
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.
Two things:
- This function never returns an
error
so that should be removed from the function signature - Nit: Since this codebase uses a very flat Go package structure, we should include the AWS service name in the expand and flatten function names
func expandProductionVariants(configured []interface{}) ([]*sagemaker.ProductionVariant, error) { | |
func expandSagemakerProductionVariants(configured []interface{}) []*sagemaker.ProductionVariant { |
if v, ok := data["initial_variant_weight"]; ok { | ||
l.InitialVariantWeight = aws.Float64(v.(float64)) | ||
} else { | ||
l.InitialVariantWeight = aws.Float64(1) |
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.
Should we add this as a Default
for the schema attribute?
|
||
for _, i := range list { | ||
l := map[string]interface{}{ | ||
"instance_type": *i.InstanceType, |
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, we should prefer to use the AWS Go SDK provided dereferencing functions here and below. We can likely also remove nil
checks below as well with them. e.g.
"instance_type": *i.InstanceType, | |
"instance_type": aws.StringValue(i.InstanceType), |
}, | ||
}, | ||
|
||
"kms_key_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.
Since the Sagemaker API Reference notes this should be an Amazon Resource Name anyways, we should consider renaming this to kms_key_arn
? We have been trying to start doing this places where we can to reduce confusion. We can also validate it partially with ValidateFunc: validateArn
} | ||
|
||
resp, err := conn.ListEndpointConfigs(&sagemaker.ListEndpointConfigsInput{ | ||
NameContains: aws.String(rs.Primary.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.
This seems like it can report false positives and should use DescribeEndpointConfig
instead, e.g.
input := &sagemaker.DescribeEndpointConfigInput{
EndpointConfigName: aws.String(rs.Primary.ID),
}
output, err := conn.DescribeEndpointConfig(input)
if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "") {
continue
}
if err != nil {
return err
}
return fmt.Errorf("Sagemaker Endpoint Configuration (%s) still exists", rs.Primary.ID)
|
||
endpointConfig, err := conn.DescribeEndpointConfig(request) | ||
if err != nil { | ||
if sagemakerErr, ok := err.(awserr.Error); ok && sagemakerErr.Code() == "ValidationException" { |
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.
Nit: We have a helper function for this type of checking:
if sagemakerErr, ok := err.(awserr.Error); ok && sagemakerErr.Code() == "ValidationException" { | |
if isAWSErr(err, "ValidationException", "") { |
|
||
* `name` - (Optional) The name of the endpoint configuration. If omitted, Terraform will assign a random, unique name. | ||
* `production_variants` - (Required) Fields are documented below. | ||
* `kms_key_id` - (Optional) KMS key to encrypt the model data. |
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.
Matching the Sagemaker API Reference (and suggested rename above)
* `kms_key_id` - (Optional) KMS key to encrypt the model data. | |
* `kms_key_arn` - (Optional) Amazon Resource Name (ARN) of a AWS Key Management Service key that Amazon SageMaker uses to encrypt data on the storage volume attached to the ML compute instance that hosts the endpoint. |
|
||
The `production_variant` block supports: | ||
|
||
* `variant_name` - (Optional) The name of the variant. If omitted, Terraform will assign a random, unique name. |
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.
Nit: These attributes should be alphabetically sorted either as a whole or required first then optional
@bflad thanks for the feedback! I will implement your feedback within the next days (probably Monday). |
9e9b90b
to
b5f26a7
Compare
b5f26a7
to
6ecd49f
Compare
@bflad I am done here. See the last commit.
|
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.
Looks great, thanks @jckuester! 🚀
--- PASS: TestAccAWSSagemakerEndpointConfiguration_Basic (35.87s)
--- PASS: TestAccAWSSagemakerEndpointConfiguration_Tags (46.12s)
--- PASS: TestAccAWSSagemakerEndpointConfiguration_ProductionVariants_AcceleratorType (50.91s)
--- PASS: TestAccAWSSagemakerEndpointConfiguration_ProductionVariants_InitialVariantWeight (62.43s)
--- PASS: TestAccAWSSagemakerEndpointConfiguration_KmsKeyId (66.03s)
This has been released in version 2.4.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! |
Please only review the last commit. The reason is that this PR depends and is rebased on #2478, as the tests need the resource
aws_sagemaker_endpoint_configuration
to work.Add the resource
aws_sagemaker_endpoint_configuration
for the newly announced service called SageMaker:Acceptance tests
Updates
kms_key_id