Skip to content

Commit 5f6ccfc

Browse files
committed
aws_sagemaker_image_version - use version, not just name, in resource id fixes #42605
1 parent d45a5fd commit 5f6ccfc

File tree

8 files changed

+167
-36
lines changed

8 files changed

+167
-36
lines changed

.changelog/42606.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
resource/aws_sagemaker_image_version: Use version as part of resource id, avoiding mix up between similar resources
3+
```

internal/service/sagemaker/image_version.go

Lines changed: 122 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ package sagemaker
55

66
import (
77
"context"
8+
"fmt"
89
"log"
10+
"strconv"
11+
"strings"
912

1013
"github.com/YakDriver/regexache"
1114
"github.com/aws/aws-sdk-go-v2/aws"
@@ -144,10 +147,22 @@ func resourceImageVersionCreate(ctx context.Context, d *schema.ResourceData, met
144147
return sdkdiag.AppendErrorf(diags, "creating SageMaker AI Image Version %s: %s", name, err)
145148
}
146149

147-
d.SetId(name)
150+
// Get the version from the API response
151+
output, err := conn.DescribeImageVersion(ctx, &sagemaker.DescribeImageVersionInput{
152+
ImageName: aws.String(name),
153+
})
154+
if err != nil {
155+
return sdkdiag.AppendErrorf(diags, "describing SageMaker AI Image Version %s after creation: %s", name, err)
156+
}
157+
158+
// Set the ID to be a combination of name and version
159+
versionNumber := aws.ToInt32(output.Version)
160+
id := fmt.Sprintf("%s:%d", name, versionNumber)
161+
d.SetId(id)
148162

149-
if _, err := waitImageVersionCreated(ctx, conn, d.Id()); err != nil {
150-
return sdkdiag.AppendErrorf(diags, "waiting for SageMaker AI Image Version (%s) to be created: %s", d.Id(), err)
163+
// Wait for the image version to be created
164+
if _, err := waitImageVersionCreated(ctx, conn, id); err != nil {
165+
return sdkdiag.AppendErrorf(diags, "waiting for SageMaker AI Image Version (%s) to be created: %s", id, err)
151166
}
152167

153168
return append(diags, resourceImageVersionRead(ctx, d, meta)...)
@@ -157,24 +172,46 @@ func resourceImageVersionRead(ctx context.Context, d *schema.ResourceData, meta
157172
var diags diag.Diagnostics
158173
conn := meta.(*conns.AWSClient).SageMakerClient(ctx)
159174

160-
image, err := findImageVersionByName(ctx, conn, d.Id())
175+
id := d.Id()
176+
var image *sagemaker.DescribeImageVersionOutput
177+
var err error
178+
179+
// Check if the ID contains a version (has a colon)
180+
if strings.Contains(id, ":") {
181+
// New format - use the new function
182+
image, err = findImageVersionByNameAndVersion(ctx, conn, id)
183+
} else {
184+
// Legacy format - just the name
185+
image, err = findImageVersionByName(ctx, conn, id)
186+
187+
// If successful, update the ID to the new format
188+
if err == nil && image != nil {
189+
newID := fmt.Sprintf("%s:%d", id, aws.ToInt32(image.Version))
190+
d.SetId(newID)
191+
id = newID
192+
}
193+
}
161194

162195
if !d.IsNewResource() && tfresource.NotFound(err) {
163196
d.SetId("")
164-
log.Printf("[WARN] Unable to find SageMaker AI Image Version (%s); removing from state", d.Id())
197+
log.Printf("[WARN] Unable to find SageMaker AI Image Version (%s); removing from state", id)
165198
return diags
166199
}
167200

168201
if err != nil {
169-
return sdkdiag.AppendErrorf(diags, "reading SageMaker AI Image Version (%s): %s", d.Id(), err)
202+
return sdkdiag.AppendErrorf(diags, "reading SageMaker AI Image Version (%s): %s", id, err)
170203
}
171204

205+
// Parse the ID to get the name
206+
parts := strings.Split(id, ":")
207+
name := parts[0]
208+
172209
d.Set(names.AttrARN, image.ImageVersionArn)
173210
d.Set("base_image", image.BaseImage)
174211
d.Set("image_arn", image.ImageArn)
175212
d.Set("container_image", image.ContainerImage)
176213
d.Set(names.AttrVersion, image.Version)
177-
d.Set("image_name", d.Id())
214+
d.Set("image_name", name)
178215
d.Set("horovod", image.Horovod)
179216
d.Set("job_type", image.JobType)
180217
d.Set("processor", image.Processor)
@@ -190,9 +227,23 @@ func resourceImageVersionUpdate(ctx context.Context, d *schema.ResourceData, met
190227
var diags diag.Diagnostics
191228
conn := meta.(*conns.AWSClient).SageMakerClient(ctx)
192229

230+
// Parse the ID to get name and version
231+
parts := strings.Split(d.Id(), ":")
232+
if len(parts) != 2 {
233+
return sdkdiag.AppendErrorf(diags, "invalid resource ID format: %s", d.Id())
234+
}
235+
236+
name := parts[0]
237+
versionStr := parts[1]
238+
239+
version, err := strconv.Atoi(versionStr)
240+
if err != nil {
241+
return sdkdiag.AppendErrorf(diags, "invalid version number in resource ID: %s", d.Id())
242+
}
243+
193244
input := &sagemaker.UpdateImageVersionInput{
194-
ImageName: aws.String(d.Id()),
195-
Version: aws.Int32(int32(d.Get(names.AttrVersion).(int))),
245+
ImageName: aws.String(name),
246+
Version: aws.Int32(int32(version)),
196247
}
197248

198249
if d.HasChange("horovod") {
@@ -234,9 +285,23 @@ func resourceImageVersionDelete(ctx context.Context, d *schema.ResourceData, met
234285
var diags diag.Diagnostics
235286
conn := meta.(*conns.AWSClient).SageMakerClient(ctx)
236287

288+
// Parse the ID to get name and version
289+
parts := strings.Split(d.Id(), ":")
290+
if len(parts) != 2 {
291+
return sdkdiag.AppendErrorf(diags, "invalid resource ID format: %s", d.Id())
292+
}
293+
294+
name := parts[0]
295+
versionStr := parts[1]
296+
297+
version, err := strconv.Atoi(versionStr)
298+
if err != nil {
299+
return sdkdiag.AppendErrorf(diags, "invalid version number in resource ID: %s", d.Id())
300+
}
301+
237302
input := &sagemaker.DeleteImageVersionInput{
238-
ImageName: aws.String(d.Id()),
239-
Version: aws.Int32(int32(d.Get(names.AttrVersion).(int))),
303+
ImageName: aws.String(name),
304+
Version: aws.Int32(int32(version)),
240305
}
241306

242307
if _, err := conn.DeleteImageVersion(ctx, input); err != nil {
@@ -253,6 +318,47 @@ func resourceImageVersionDelete(ctx context.Context, d *schema.ResourceData, met
253318
return diags
254319
}
255320

321+
func findImageVersionByNameAndVersion(ctx context.Context, conn *sagemaker.Client, id string) (*sagemaker.DescribeImageVersionOutput, error) {
322+
// Parse the ID to get name and version
323+
parts := strings.Split(id, ":")
324+
if len(parts) != 2 {
325+
return nil, fmt.Errorf("invalid resource ID format: %s", id)
326+
}
327+
328+
name := parts[0]
329+
versionStr := parts[1]
330+
331+
version, err := strconv.Atoi(versionStr)
332+
if err != nil {
333+
return nil, fmt.Errorf("invalid version number in resource ID: %s", id)
334+
}
335+
336+
input := &sagemaker.DescribeImageVersionInput{
337+
ImageName: aws.String(name),
338+
Version: aws.Int32(int32(version)),
339+
}
340+
341+
output, err := conn.DescribeImageVersion(ctx, input)
342+
343+
if errs.IsAErrorMessageContains[*awstypes.ResourceNotFound](err, "does not exist") {
344+
return nil, &retry.NotFoundError{
345+
LastError: err,
346+
LastRequest: input,
347+
}
348+
}
349+
350+
if err != nil {
351+
return nil, err
352+
}
353+
354+
if output == nil {
355+
return nil, tfresource.NewEmptyResultError(input)
356+
}
357+
358+
return output, nil
359+
}
360+
361+
// Keep this for backward compatibility
256362
func findImageVersionByName(ctx context.Context, conn *sagemaker.Client, name string) (*sagemaker.DescribeImageVersionOutput, error) {
257363
input := &sagemaker.DescribeImageVersionInput{
258364
ImageName: aws.String(name),
@@ -277,3 +383,8 @@ func findImageVersionByName(ctx context.Context, conn *sagemaker.Client, name st
277383

278384
return output, nil
279385
}
386+
387+
// FindImageVersionByNameAndVersion finds a SageMaker Image Version by name and version
388+
func FindImageVersionByNameAndVersion(ctx context.Context, conn *sagemaker.Client, id string) (*sagemaker.DescribeImageVersionOutput, error) {
389+
return findImageVersionByNameAndVersion(ctx, conn, id)
390+
}

internal/service/sagemaker/image_version_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func testAccCheckImageVersionDestroy(ctx context.Context) resource.TestCheckFunc
191191
continue
192192
}
193193

194-
_, err := tfsagemaker.FindImageVersionByName(ctx, conn, rs.Primary.ID)
194+
_, err := tfsagemaker.FindImageVersionByNameAndVersion(ctx, conn, rs.Primary.ID)
195195

196196
if tfresource.NotFound(err) {
197197
continue
@@ -220,7 +220,7 @@ func testAccCheckImageVersionExists(ctx context.Context, n string, image *sagema
220220
}
221221

222222
conn := acctest.Provider.Meta().(*conns.AWSClient).SageMakerClient(ctx)
223-
resp, err := tfsagemaker.FindImageVersionByName(ctx, conn, rs.Primary.ID)
223+
resp, err := tfsagemaker.FindImageVersionByNameAndVersion(ctx, conn, rs.Primary.ID)
224224
if err != nil {
225225
return err
226226
}

internal/service/sagemaker/status.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package sagemaker
55

66
import (
77
"context"
8+
"strings"
89

910
"github.com/aws/aws-sdk-go-v2/service/sagemaker"
1011
awstypes "github.com/aws/aws-sdk-go-v2/service/sagemaker/types"
@@ -60,9 +61,19 @@ func statusImage(ctx context.Context, conn *sagemaker.Client, name string) retry
6061
}
6162
}
6263

63-
func statusImageVersion(ctx context.Context, conn *sagemaker.Client, name string) retry.StateRefreshFunc {
64+
func statusImageVersion(ctx context.Context, conn *sagemaker.Client, id string) retry.StateRefreshFunc {
6465
return func() (any, string, error) {
65-
output, err := findImageVersionByName(ctx, conn, name)
66+
// Check if the ID contains a version (has a colon)
67+
var output *sagemaker.DescribeImageVersionOutput
68+
var err error
69+
70+
if strings.Contains(id, ":") {
71+
// New format - use the new function
72+
output, err = findImageVersionByNameAndVersion(ctx, conn, id)
73+
} else {
74+
// Legacy format - just the name
75+
output, err = findImageVersionByName(ctx, conn, id)
76+
}
6677

6778
if tfresource.NotFound(err) {
6879
return nil, "", nil

internal/service/sagemaker/wait.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ func waitImageDeleted(ctx context.Context, conn *sagemaker.Client, name string)
213213
return err
214214
}
215215

216-
func waitImageVersionCreated(ctx context.Context, conn *sagemaker.Client, name string) (*sagemaker.DescribeImageVersionOutput, error) {
216+
func waitImageVersionCreated(ctx context.Context, conn *sagemaker.Client, id string) (*sagemaker.DescribeImageVersionOutput, error) {
217217
stateConf := &retry.StateChangeConf{
218218
Pending: enum.Slice(awstypes.ImageVersionStatusCreating),
219219
Target: enum.Slice(awstypes.ImageVersionStatusCreated),
220-
Refresh: statusImageVersion(ctx, conn, name),
220+
Refresh: statusImageVersion(ctx, conn, id),
221221
Timeout: imageVersionCreatedTimeout,
222222
}
223223

@@ -234,11 +234,11 @@ func waitImageVersionCreated(ctx context.Context, conn *sagemaker.Client, name s
234234
return nil, err
235235
}
236236

237-
func waitImageVersionDeleted(ctx context.Context, conn *sagemaker.Client, name string) (*sagemaker.DescribeImageVersionOutput, error) {
237+
func waitImageVersionDeleted(ctx context.Context, conn *sagemaker.Client, id string) (*sagemaker.DescribeImageVersionOutput, error) {
238238
stateConf := &retry.StateChangeConf{
239239
Pending: enum.Slice(awstypes.ImageVersionStatusDeleting),
240240
Target: []string{},
241-
Refresh: statusImageVersion(ctx, conn, name),
241+
Refresh: statusImageVersion(ctx, conn, id),
242242
Timeout: imageVersionDeletedTimeout,
243243
}
244244

website/docs/cdktf/python/r/sagemaker_image_version.html.markdown

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@ This resource supports the following arguments:
5252

5353
This resource exports the following attributes in addition to the arguments above:
5454

55-
* `id` - The name of the Image.
55+
* `id` - The image name and version in the format `name:version`.
5656
* `arn` - The Amazon Resource Name (ARN) assigned by AWS to this Image Version.
5757
* `version`- The version of the image. If not specified, the latest version is described.
5858
* `container_image` - The registry path of the container image that contains this image version.
5959

6060
## Import
6161

62-
In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import SageMaker AI Image Versions using the `name`. For example:
62+
In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import SageMaker AI Image Versions using the `name:version` format. For example:
6363

6464
```python
6565
# DO NOT EDIT. Code generated by 'cdktf convert' - Please report bugs at https://cdk.tf/bug
@@ -73,13 +73,15 @@ from imports.aws.sagemaker_image_version import SagemakerImageVersion
7373
class MyConvertedCode(TerraformStack):
7474
def __init__(self, scope, name):
7575
super().__init__(scope, name)
76-
SagemakerImageVersion.generate_config_for_import(self, "testImage", "my-code-repo")
76+
SagemakerImageVersion.generate_config_for_import(self, "testImage", "my-image:1")
7777
```
7878

79-
Using `terraform import`, import SageMaker AI Image Versions using the `name`. For example:
79+
Using `terraform import`, import SageMaker AI Image Versions using the `name:version` format. For example:
8080

8181
```console
82-
% terraform import aws_sagemaker_image_version.test_image my-code-repo
82+
% terraform import aws_sagemaker_image_version.test_image my-image:1
8383
```
8484

85-
<!-- cache-key: cdktf-0.20.8 input-2b65cb576f99597961832b17ffc716ded699a4a561e60f3d09bc1a312c687a14 -->
85+
For backward compatibility, importing using just the image name is still supported, but the resource ID will be automatically updated to the `name:version` format after import.
86+
87+
<!-- cache-key: cdktf-0.20.8 input-2b65cb576f99597961832b17ffc716ded699a4a561e60f3d09bc1a312c687a14 -->

website/docs/cdktf/typescript/r/sagemaker_image_version.html.markdown

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ This resource supports the following arguments:
5555

5656
This resource exports the following attributes in addition to the arguments above:
5757

58-
* `id` - The name of the Image.
58+
* `id` - The image name and version in the format `name:version`.
5959
* `arn` - The Amazon Resource Name (ARN) assigned by AWS to this Image Version.
6060
* `version`- The version of the image. If not specified, the latest version is described.
6161
* `containerImage` - The registry path of the container image that contains this image version.
6262

6363
## Import
6464

65-
In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import SageMaker AI Image Versions using the `name`. For example:
65+
In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import SageMaker AI Image Versions using the `name:version` format. For example:
6666

6767
```typescript
6868
// DO NOT EDIT. Code generated by 'cdktf convert' - Please report bugs at https://cdk.tf/bug
@@ -79,17 +79,19 @@ class MyConvertedCode extends TerraformStack {
7979
SagemakerImageVersion.generateConfigForImport(
8080
this,
8181
"testImage",
82-
"my-code-repo"
82+
"my-image:1"
8383
);
8484
}
8585
}
8686

8787
```
8888

89-
Using `terraform import`, import SageMaker AI Image Versions using the `name`. For example:
89+
Using `terraform import`, import SageMaker AI Image Versions using the `name:version` format. For example:
9090

9191
```console
92-
% terraform import aws_sagemaker_image_version.test_image my-code-repo
92+
% terraform import aws_sagemaker_image_version.test_image my-image:1
9393
```
9494

95-
<!-- cache-key: cdktf-0.20.8 input-2b65cb576f99597961832b17ffc716ded699a4a561e60f3d09bc1a312c687a14 -->
95+
For backward compatibility, importing using just the image name is still supported, but the resource ID will be automatically updated to the `name:version` format after import.
96+
97+
<!-- cache-key: cdktf-0.20.8 input-2b65cb576f99597961832b17ffc716ded699a4a561e60f3d09bc1a312c687a14 -->

website/docs/r/sagemaker_image_version.html.markdown

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,26 @@ This resource supports the following arguments:
3939

4040
This resource exports the following attributes in addition to the arguments above:
4141

42-
* `id` - The name of the Image.
42+
* `id` - The image name and version in the format `name:version`.
4343
* `arn` - The Amazon Resource Name (ARN) assigned by AWS to this Image Version.
4444
* `version`- The version of the image. If not specified, the latest version is described.
4545
* `container_image` - The registry path of the container image that contains this image version.
4646

4747
## Import
4848

49-
In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import SageMaker AI Image Versions using the `name`. For example:
49+
In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import SageMaker AI Image Versions using the `name:version` format. For example:
5050

5151
```terraform
5252
import {
5353
to = aws_sagemaker_image_version.test_image
54-
id = "my-code-repo"
54+
id = "my-image:1"
5555
}
5656
```
5757

58-
Using `terraform import`, import SageMaker AI Image Versions using the `name`. For example:
58+
Using `terraform import`, import SageMaker AI Image Versions using the `name:version` format. For example:
5959

6060
```console
61-
% terraform import aws_sagemaker_image_version.test_image my-code-repo
61+
% terraform import aws_sagemaker_image_version.test_image my-image:1
6262
```
63+
64+
For backward compatibility, importing using just the image name is still supported, but the resource ID will be automatically updated to the `name:version` format after import.

0 commit comments

Comments
 (0)