Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/44795.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-data-source
aws_ecrpublic_images
```
134 changes: 134 additions & 0 deletions internal/service/ecrpublic/images_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package ecrpublic

import (
"context"

"github.com/YakDriver/regexache"
"github.com/aws/aws-sdk-go-v2/service/ecrpublic"
awstypes "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types"
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types"
"github.com/hashicorp/terraform-provider-aws/internal/smerr"
"github.com/hashicorp/terraform-provider-aws/names"
)

// @FrameworkDataSource("aws_ecrpublic_images", name="Images")
func newDataSourceImages(_ context.Context) (datasource.DataSourceWithConfigure, error) {
return &dataSourceImages{}, nil
}

type dataSourceImages struct {
framework.DataSourceWithModel[dataSourceImagesModel]
}

func (d *dataSourceImages) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Provides details about AWS ECR Public Images in a public repository.",
Attributes: map[string]schema.Attribute{
names.AttrRepositoryName: schema.StringAttribute{
Description: "Name of the public repository.",
Required: true,
Validators: []validator.String{
stringvalidator.LengthBetween(2, 205),
},
},
"registry_id": schema.StringAttribute{
Description: "AWS account ID associated with the public registry that contains the repository. If not specified, the default public registry is assumed.",
Optional: true,
Validators: []validator.String{
stringvalidator.RegexMatches(regexache.MustCompile(`^[0-9]{12}$`), "must be a 12-digit AWS account ID"),
},
},
"images": framework.DataSourceComputedListOfObjectAttribute[imageItemModel](ctx),
},
Blocks: map[string]schema.Block{
"image_ids": schema.ListNestedBlock{
Description: "List of image IDs to filter. Each image ID can use either a tag or digest.",
CustomType: fwtypes.NewListNestedObjectTypeOf[imagesIDsModel](ctx),
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"image_tag": schema.StringAttribute{
Description: "Image tag.",
Optional: true,
},
"image_digest": schema.StringAttribute{
Description: "Image digest.",
Optional: true,
},
},
},
},
},
}
}

func (d *dataSourceImages) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data dataSourceImagesModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

conn := d.Meta().ECRPublicClient(ctx)

var input ecrpublic.DescribeImagesInput
resp.Diagnostics.Append(fwflex.Expand(ctx, &data, &input)...)
if resp.Diagnostics.HasError() {
return
}

var images []awstypes.ImageDetail

paginator := ecrpublic.NewDescribeImagesPaginator(conn, &input)
for paginator.HasMorePages() {
output, err := paginator.NextPage(ctx)

if err != nil {
smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, data.RepositoryName.String())
return
}

images = append(images, output.ImageDetails...)
}

resp.Diagnostics.Append(fwflex.Flatten(ctx, images, &data.Images)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

type dataSourceImagesModel struct {
framework.WithRegionModel
RepositoryName types.String `tfsdk:"repository_name"`
RegistryId types.String `tfsdk:"registry_id"`
ImageIds fwtypes.ListNestedObjectValueOf[imagesIDsModel] `tfsdk:"image_ids"`
Images fwtypes.ListNestedObjectValueOf[imageItemModel] `tfsdk:"images"`
}

type imagesIDsModel struct {
ImageTag types.String `tfsdk:"image_tag"`
ImageDigest types.String `tfsdk:"image_digest"`
}

type imageItemModel struct {
ArtifactMediaType types.String `tfsdk:"artifact_media_type"`
ImageDigest types.String `tfsdk:"image_digest"`
ImageManifestMediaType types.String `tfsdk:"image_manifest_media_type"`
ImagePushedAt timetypes.RFC3339 `tfsdk:"image_pushed_at"`
ImageSizeInBytes types.Int64 `tfsdk:"image_size_in_bytes"`
ImageTags fwtypes.ListValueOf[types.String] `tfsdk:"image_tags"`
RegistryId types.String `tfsdk:"registry_id"`
RepositoryName types.String `tfsdk:"repository_name"`
}
116 changes: 116 additions & 0 deletions internal/service/ecrpublic/images_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package ecrpublic_test

import (
"fmt"
"testing"

"github.com/YakDriver/regexache"
"github.com/hashicorp/aws-sdk-go-base/v2/endpoints"
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/names"
)

func TestAccECRPublicImagesDataSource_basic(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
dataSourceName := "data.aws_ecrpublic_images.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckRegion(t, endpoints.UsEast1RegionID) },
ErrorCheck: acctest.ErrorCheck(t, names.ECRPublicServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccImagesDataSourceConfig_basic(rName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, names.AttrRepositoryName, rName),
resource.TestCheckResourceAttr(dataSourceName, "images.#", "0"),
),
},
},
})
}

func TestAccECRPublicImagesDataSource_registryID(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
dataSourceName := "data.aws_ecrpublic_images.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckRegion(t, endpoints.UsEast1RegionID) },
ErrorCheck: acctest.ErrorCheck(t, names.ECRPublicServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccImagesDataSourceConfig_registryID(rName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, names.AttrRepositoryName, rName),
resource.TestCheckResourceAttrSet(dataSourceName, "registry_id"),
resource.TestCheckResourceAttr(dataSourceName, "images.#", "0"),
),
},
},
})
}

func TestAccECRPublicImagesDataSource_registryIDValidation(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckRegion(t, endpoints.UsEast1RegionID) },
ErrorCheck: acctest.ErrorCheck(t, names.ECRPublicServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccImagesDataSourceConfig_registryIDInvalid(rName),
ExpectError: regexache.MustCompile(`must be a 12-digit AWS account ID`),
},
},
})
}

func testAccImagesDataSourceConfig_basic(rName string) string {
return fmt.Sprintf(`
resource "aws_ecrpublic_repository" "test" {
repository_name = %[1]q
}

data "aws_ecrpublic_images" "test" {
repository_name = aws_ecrpublic_repository.test.repository_name
}
`, rName)
}

func testAccImagesDataSourceConfig_registryID(rName string) string {
return fmt.Sprintf(`
data "aws_caller_identity" "current" {}

resource "aws_ecrpublic_repository" "test" {
repository_name = %[1]q
}

data "aws_ecrpublic_images" "test" {
repository_name = aws_ecrpublic_repository.test.repository_name
registry_id = data.aws_caller_identity.current.account_id
}
`, rName)
}

func testAccImagesDataSourceConfig_registryIDInvalid(rName string) string {
return fmt.Sprintf(`
resource "aws_ecrpublic_repository" "test" {
repository_name = %[1]q
}

data "aws_ecrpublic_images" "test" {
repository_name = aws_ecrpublic_repository.test.repository_name
registry_id = "invalid"
}
`, rName)
}
9 changes: 8 additions & 1 deletion internal/service/ecrpublic/service_package_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions website/docs/d/ecrpublic_images.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
subcategory: "ECR Public"
layout: "aws"
page_title: "AWS: aws_ecrpublic_images"
description: |-
Provides a list of images for a specified AWS ECR Public Repository.
---

# Data Source: aws_ecrpublic_images

The ECR Public Images data source allows the list of images in a specified public repository to be retrieved.

## Example Usage

```terraform
data "aws_ecrpublic_images" "example" {
repository_name = "my-public-repository"
}

output "image_digests" {
value = [for img in data.aws_ecrpublic_images.example.images : img.digest if img.digest != null]
}

output "image_tags" {
value = distinct(flatten([for img in data.aws_ecrpublic_images.example.images : img.tags]))
}
```

## Argument Reference

This data source supports the following arguments:

* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference).
* `repository_name` - (Required) Name of the public repository.
* `registry_id` - (Optional) AWS account ID associated with the public registry that contains the repository. If not specified, the default public registry is assumed.
* `image_ids` - (Optional) One or more image ID filters. Each image ID can use either a tag or digest (or both). Each object has the following attributes:
* `image_tag` - (Optional) Tag used for the image.
* `image_digest` - (Optional) Digest of the image manifest.

## Attribute Reference

This data source exports the following attributes in addition to the arguments above:

* `images` - List of images returned. Each image contains:
* `digest` - Image digest.
* `tags` - List of image tags.
* `size_in_bytes` - Image size in bytes.
* `pushed_at` - Timestamp when image was pushed.
* `artifact_media_type` - Media type of the artifact.
* `image_manifest_media_type` - Media type of the image manifest.
* `registry_id` - AWS account ID associated with the public registry.
* `repository_name` - Name of the repository.
Loading