Skip to content
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

Add image scanning to imagebuilder image pipeline resource #33005

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cb3dd92
Adding image scanning option to resource
stromp Aug 8, 2023
df0c412
changing test to correct value
stromp Aug 8, 2023
43abfe3
added advanced test, still need to fix assertions
stromp Aug 8, 2023
ed91a6a
- add image scanning attributes to the data resource
stromp Aug 10, 2023
84d3246
Update documentation
stromp Aug 10, 2023
156c150
fix formatting
stromp Aug 10, 2023
4d62eca
fix formatting
stromp Aug 15, 2023
3eb8c74
add changelog
stromp Aug 15, 2023
856a017
Merge branch 'main' into HEAD
ewbankkit Aug 16, 2023
a73a21b
Correct CHANGELOG entries.
ewbankkit Aug 16, 2023
d8216b8
Fix terrafmt errors in acceptance test configurations.
ewbankkit Aug 16, 2023
fad9420
Fix semgrep 'ci.caps3-in-func-name '.
ewbankkit Aug 16, 2023
90d4832
r/aws_imagebuilder_image_pipeline: Alphabetize attributes.
ewbankkit Aug 16, 2023
3e1e5f8
d/aws_imagebuilder_image_pipeline: Alphabetize attributes.
ewbankkit Aug 16, 2023
d96c986
d/aws_imagebuilder_image_pipeline: Tidy up acceptance tests.
ewbankkit Aug 16, 2023
f883b24
r/aws_imagebuilder_image_pipeline: Tidy up acceptance tests.
ewbankkit Aug 16, 2023
32188bd
Fix terrafmt error.
ewbankkit Aug 16, 2023
4cc635f
Fix
ewbankkit Aug 16, 2023
28f55a2
imagebuilder: Ignore acceptance test errors like 'creating Image Buil…
ewbankkit Aug 16, 2023
cd317c0
Fix 'TestAccImageBuilderImagePipeline_containerRecipeARN'.
ewbankkit Aug 16, 2023
3f9ff8f
Ignore 'date_next_run' for import tests.
ewbankkit Aug 16, 2023
52ea7c4
Fix 'TestAccImageBuilderDistributionConfigurationDataSource_arn'.
ewbankkit Aug 16, 2023
0ef43f8
Fix 'TestAccImageBuilderDistributionConfiguration_DistributionFastLau…
ewbankkit Aug 16, 2023
67c93c6
Fix 'TestAccImageBuilderImageRecipesDataSource_owner'.
ewbankkit Aug 16, 2023
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
7 changes: 7 additions & 0 deletions .changelog/33005.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_imagebuilder_image_pipeline: Add `image_scanning_configuration` configuration block
```

```release-note:enhancement
data-source/aws_imagebuilder_image_pipeline: Add `image_scanning_configuration` attribute
```
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ resource "aws_imagebuilder_distribution_configuration" "test" {
launch_template_version = "1"
}

max_parallel_launches = 1
max_parallel_launches = 6

snapshot_configuration {
target_resource_count = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func init() {
func testAccErrorCheckSkip(t *testing.T) resource.ErrorCheckFunc {
return acctest.ErrorCheckSkipMessagesContaining(t,
"You have reached the maximum allowed number of license configurations created in one day",
"Amazon Inspector is not enabled",
)
}

Expand Down Expand Up @@ -703,12 +704,12 @@ func TestAccImageBuilderDistributionConfiguration_DistributionFastLaunchConfigur
CheckDestroy: testAccCheckDistributionConfigurationDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccDistributionConfigurationConfig_fastLaunchMaxParallelLaunches(rName, 5),
Config: testAccDistributionConfigurationConfig_fastLaunchMaxParallelLaunches(rName, 7),
Check: resource.ComposeTestCheckFunc(
testAccCheckDistributionConfigurationExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"),
resource.TestCheckResourceAttr(resourceName, "distribution.0.fast_launch_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "distribution.0.fast_launch_configuration.0.max_parallel_launches", "5"),
resource.TestCheckResourceAttr(resourceName, "distribution.0.fast_launch_configuration.0.max_parallel_launches", "7"),
),
},
{
Expand Down
127 changes: 123 additions & 4 deletions internal/service/imagebuilder/image_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
"github.com/hashicorp/terraform-provider-aws/names"
Expand Down Expand Up @@ -84,6 +85,42 @@ func ResourceImagePipeline() *schema.Resource {
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^arn:aws[^:]*:imagebuilder:[^:]+:(?:\d{12}|aws):image-recipe/[a-z0-9-_]+/\d+\.\d+\.\d+$`), "valid image recipe ARN must be provided"),
ExactlyOneOf: []string{"container_recipe_arn", "image_recipe_arn"},
},
"image_scanning_configuration": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ecr_configuration": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"container_tags": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"repository_name": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
"image_scanning_enabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
},
},
"image_tests_configuration": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -188,6 +225,10 @@ func resourceImagePipelineCreate(ctx context.Context, d *schema.ResourceData, me
input.ImageRecipeArn = aws.String(v.(string))
}

if v, ok := d.GetOk("image_scanning_configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input.ImageScanningConfiguration = expandImageScanningConfiguration(v.([]interface{})[0].(map[string]interface{}))
}

if v, ok := d.GetOk("image_tests_configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input.ImageTestsConfiguration = expandImageTestConfiguration(v.([]interface{})[0].(map[string]interface{}))
}
Expand Down Expand Up @@ -259,23 +300,24 @@ func resourceImagePipelineRead(ctx context.Context, d *schema.ResourceData, meta
d.Set("distribution_configuration_arn", imagePipeline.DistributionConfigurationArn)
d.Set("enhanced_image_metadata_enabled", imagePipeline.EnhancedImageMetadataEnabled)
d.Set("image_recipe_arn", imagePipeline.ImageRecipeArn)

if imagePipeline.ImageScanningConfiguration != nil {
d.Set("image_scanning_configuration", []interface{}{flattenImageScanningConfiguration(imagePipeline.ImageScanningConfiguration)})
} else {
d.Set("image_scanning_configuration", nil)
}
if imagePipeline.ImageTestsConfiguration != nil {
d.Set("image_tests_configuration", []interface{}{flattenImageTestsConfiguration(imagePipeline.ImageTestsConfiguration)})
} else {
d.Set("image_tests_configuration", nil)
}

d.Set("infrastructure_configuration_arn", imagePipeline.InfrastructureConfigurationArn)
d.Set("name", imagePipeline.Name)
d.Set("platform", imagePipeline.Platform)

if imagePipeline.Schedule != nil {
d.Set("schedule", []interface{}{flattenSchedule(imagePipeline.Schedule)})
} else {
d.Set("schedule", nil)
}

d.Set("status", imagePipeline.Status)

setTagsOut(ctx, imagePipeline.Tags)
Expand All @@ -291,6 +333,7 @@ func resourceImagePipelineUpdate(ctx context.Context, d *schema.ResourceData, me
"description",
"distribution_configuration_arn",
"enhanced_image_metadata_enabled",
"image_scanning_configuration",
"image_tests_configuration",
"infrastructure_configuration_arn",
"schedule",
Expand Down Expand Up @@ -318,6 +361,10 @@ func resourceImagePipelineUpdate(ctx context.Context, d *schema.ResourceData, me
input.ImageRecipeArn = aws.String(v.(string))
}

if v, ok := d.GetOk("image_scanning_configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input.ImageScanningConfiguration = expandImageScanningConfiguration(v.([]interface{})[0].(map[string]interface{}))
}

if v, ok := d.GetOk("image_tests_configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input.ImageTestsConfiguration = expandImageTestConfiguration(v.([]interface{})[0].(map[string]interface{}))
}
Expand Down Expand Up @@ -365,6 +412,42 @@ func resourceImagePipelineDelete(ctx context.Context, d *schema.ResourceData, me
return diags
}

func expandImageScanningConfiguration(tfMap map[string]interface{}) *imagebuilder.ImageScanningConfiguration {
if tfMap == nil {
return nil
}

apiObject := &imagebuilder.ImageScanningConfiguration{}

if v, ok := tfMap["image_scanning_enabled"].(bool); ok {
apiObject.ImageScanningEnabled = aws.Bool(v)
}

if v, ok := tfMap["ecr_configuration"].([]interface{}); ok && len(v) > 0 && v[0] != nil {
apiObject.EcrConfiguration = expandECRConfiguration(v[0].(map[string]interface{}))
}

return apiObject
}

func expandECRConfiguration(tfMap map[string]interface{}) *imagebuilder.EcrConfiguration {
if tfMap == nil {
return nil
}

apiObject := &imagebuilder.EcrConfiguration{}

if v, ok := tfMap["container_tags"].(*schema.Set); ok {
apiObject.ContainerTags = flex.ExpandStringSet(v)
}

if v, ok := tfMap["repository_name"].(string); ok {
apiObject.RepositoryName = aws.String(v)
}

return apiObject
}

func expandImageTestConfiguration(tfMap map[string]interface{}) *imagebuilder.ImageTestsConfiguration {
if tfMap == nil {
return nil
Expand Down Expand Up @@ -405,6 +488,42 @@ func expandPipelineSchedule(tfMap map[string]interface{}) *imagebuilder.Schedule
return apiObject
}

func flattenImageScanningConfiguration(apiObject *imagebuilder.ImageScanningConfiguration) map[string]interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if v := apiObject.ImageScanningEnabled; v != nil {
tfMap["image_scanning_enabled"] = aws.BoolValue(v)
}

if v := apiObject.EcrConfiguration; v != nil {
tfMap["ecr_configuration"] = []interface{}{flattenECRConfiguration(v)}
}

return tfMap
}

func flattenECRConfiguration(apiObject *imagebuilder.EcrConfiguration) map[string]interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if v := apiObject.RepositoryName; v != nil {
tfMap["repository_name"] = aws.StringValue(v)
}

if v := apiObject.ContainerTags; v != nil {
tfMap["container_tags"] = aws.StringValueSlice(v)
}

return tfMap
}

func flattenImageTestsConfiguration(apiObject *imagebuilder.ImageTestsConfiguration) map[string]interface{} {
if apiObject == nil {
return nil
Expand Down
39 changes: 36 additions & 3 deletions internal/service/imagebuilder/image_pipeline_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,37 @@ func DataSourceImagePipeline() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"image_scanning_configuration": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ecr_configuration": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"container_tags": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"repository_name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"image_scanning_enabled": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
"image_tests_configuration": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -149,17 +180,19 @@ func dataSourceImagePipelineRead(ctx context.Context, d *schema.ResourceData, me
d.Set("distribution_configuration_arn", imagePipeline.DistributionConfigurationArn)
d.Set("enhanced_image_metadata_enabled", imagePipeline.EnhancedImageMetadataEnabled)
d.Set("image_recipe_arn", imagePipeline.ImageRecipeArn)

if imagePipeline.ImageScanningConfiguration != nil {
d.Set("image_scanning_configuration", []interface{}{flattenImageScanningConfiguration(imagePipeline.ImageScanningConfiguration)})
} else {
d.Set("image_scanning_configuration", nil)
}
if imagePipeline.ImageTestsConfiguration != nil {
d.Set("image_tests_configuration", []interface{}{flattenImageTestsConfiguration(imagePipeline.ImageTestsConfiguration)})
} else {
d.Set("image_tests_configuration", nil)
}

d.Set("infrastructure_configuration_arn", imagePipeline.InfrastructureConfigurationArn)
d.Set("name", imagePipeline.Name)
d.Set("platform", imagePipeline.Platform)

if imagePipeline.Schedule != nil {
d.Set("schedule", []interface{}{flattenSchedule(imagePipeline.Schedule)})
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestAccImageBuilderImagePipelineDataSource_arn(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccImagePipelineDataSourceConfig_arn(rName),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "container_recipe_arn", resourceName, "container_recipe_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "date_created", resourceName, "date_created"),
Expand All @@ -38,6 +38,7 @@ func TestAccImageBuilderImagePipelineDataSource_arn(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName, "distribution_configuration_arn", resourceName, "distribution_configuration_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "enhanced_image_metadata_enabled", resourceName, "enhanced_image_metadata_enabled"),
resource.TestCheckResourceAttrPair(dataSourceName, "image_recipe_arn", resourceName, "image_recipe_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "image_scanning_configuration.#", resourceName, "image_scanning_configuration.#"),
resource.TestCheckResourceAttrPair(dataSourceName, "image_tests_configuration.#", resourceName, "image_tests_configuration.#"),
resource.TestCheckResourceAttrPair(dataSourceName, "infrastructure_configuration_arn", resourceName, "infrastructure_configuration_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"),
Expand Down Expand Up @@ -65,16 +66,17 @@ func TestAccImageBuilderImagePipelineDataSource_containerRecipeARN(t *testing.T)
Steps: []resource.TestStep{
{
Config: testAccImagePipelineDataSourceConfig_containerRecipeARN(rName),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "container_recipe_arn", resourceName, "container_recipe_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "image_scanning_configuration.#", resourceName, "image_scanning_configuration.#"),
),
},
},
})
}

func testAccImagePipelineBaseDataSourceConfig(rName string) string {
func testAccImagePipelineDataSourceConfig_base(rName string) string {
return fmt.Sprintf(`
data "aws_region" "current" {}

Expand Down Expand Up @@ -128,9 +130,7 @@ resource "aws_imagebuilder_infrastructure_configuration" "test" {
}

func testAccImagePipelineDataSourceConfig_arn(rName string) string {
return acctest.ConfigCompose(
testAccImagePipelineBaseDataSourceConfig(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccImagePipelineDataSourceConfig_base(rName), fmt.Sprintf(`
resource "aws_imagebuilder_image_recipe" "test" {
component {
component_arn = aws_imagebuilder_component.test.arn
Expand All @@ -154,9 +154,7 @@ data "aws_imagebuilder_image_pipeline" "test" {
}

func testAccImagePipelineDataSourceConfig_containerRecipeARN(rName string) string {
return acctest.ConfigCompose(
testAccImagePipelineBaseDataSourceConfig(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccImagePipelineDataSourceConfig_base(rName), fmt.Sprintf(`
resource "aws_ecr_repository" "test" {
name = %[1]q
}
Expand Down Expand Up @@ -187,6 +185,15 @@ resource "aws_imagebuilder_image_pipeline" "test" {
container_recipe_arn = aws_imagebuilder_container_recipe.test.arn
infrastructure_configuration_arn = aws_imagebuilder_infrastructure_configuration.test.arn
name = %[1]q

image_scanning_configuration {
image_scanning_enabled = true

ecr_configuration {
container_tags = ["a", "b"]
repository_name = aws_ecr_repository.test.name
}
}
}

data "aws_imagebuilder_image_pipeline" "test" {
Expand Down
Loading