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

r/aws_imagebuilder_image_recipe - add support for component parameters #22837

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/22837.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_imagebuilder_image_recipe: Add `parameter` argument to the `component` configuration block
```
109 changes: 109 additions & 0 deletions internal/service/imagebuilder/image_recipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,23 @@ func ResourceImageRecipe() *schema.Resource {
Required: true,
ValidateFunc: verify.ValidARN,
},
"parameter": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringLenBetween(1, 256),
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -367,6 +384,56 @@ func expandComponentConfiguration(tfMap map[string]interface{}) *imagebuilder.Co
apiObject.ComponentArn = aws.String(v)
}

if v, ok := tfMap["parameter"].(*schema.Set); ok && v.Len() > 0 {
apiObject.Parameters = expandComponentParameters(v.List())
}

return apiObject
}

func expandComponentParameters(tfList []interface{}) []*imagebuilder.ComponentParameter {
if len(tfList) == 0 {
return nil
}

var apiObjects []*imagebuilder.ComponentParameter

for _, tfMapRaw := range tfList {
tfMap, ok := tfMapRaw.(map[string]interface{})

if !ok {
continue
}

apiObject := expandComponentParameter(tfMap)

if apiObject == nil {
continue
}

apiObjects = append(apiObjects, apiObject)
}

return apiObjects
}

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

apiObject := &imagebuilder.ComponentParameter{}

if v, ok := tfMap["name"].(string); ok && v != "" {
apiObject.Name = aws.String(v)
}

if v, ok := tfMap["value"].(string); ok && v != "" {
// ImageBuilder API quirk
// Even though Value is a slice, only one element is accepted.
apiObject.Value = aws.StringSlice([]string{v})
}

return apiObject
}

Expand Down Expand Up @@ -499,6 +566,48 @@ func flattenComponentConfiguration(apiObject *imagebuilder.ComponentConfiguratio
tfMap["component_arn"] = aws.StringValue(v)
}

if v := apiObject.Parameters; v != nil {
tfMap["parameter"] = flattenComponentParameters(v)
}

return tfMap
}

func flattenComponentParameters(apiObjects []*imagebuilder.ComponentParameter) []interface{} {
if len(apiObjects) == 0 {
return nil
}

var tfList []interface{}

for _, apiObject := range apiObjects {
if apiObject == nil {
continue
}

tfList = append(tfList, flattenComponentParameter(apiObject))
}

return tfList
}

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

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

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

if v := apiObject.Value; v != nil {
// ImageBuilder API quirk
// Even though Value is a slice, only one element is accepted.
tfMap["value"] = aws.StringValueSlice(v)[0]
}

return tfMap
}

Expand Down
78 changes: 78 additions & 0 deletions internal/service/imagebuilder/image_recipe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,32 @@ func TestAccImageBuilderImageRecipe_component(t *testing.T) {
})
}

func TestAccImageBuilderImageRecipe_componentParameter(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_imagebuilder_image_recipe.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, imagebuilder.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckImageRecipeDestroy,
Steps: []resource.TestStep{
{
Config: testAccImageRecipeComponentParameterConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckImageRecipeExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "component.#", "1"),
resource.TestCheckResourceAttr(resourceName, "component.0.parameter.#", "2"),
resource.TestCheckResourceAttr(resourceName, "component.0.parameter.0.name", "Parameter1"),
resource.TestCheckResourceAttr(resourceName, "component.0.parameter.0.value", "Value1"),
resource.TestCheckResourceAttr(resourceName, "component.0.parameter.1.name", "Parameter2"),
resource.TestCheckResourceAttr(resourceName, "component.0.parameter.1.value", "Value2"),
),
},
},
})
}

func TestAccImageBuilderImageRecipe_description(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_imagebuilder_image_recipe.test"
Expand Down Expand Up @@ -910,6 +936,58 @@ resource "aws_imagebuilder_image_recipe" "test" {
`, rName))
}

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

data "aws_partition" "current" {}

resource "aws_imagebuilder_component" "test" {
data = <<EOF
phases:
- name: build
steps:
- name: example
action: ExecuteBash
inputs:
commands:
- echo {{ Parameter1 }}
- echo {{ Parameter2 }}
parameters:
- Parameter1:
type: string
- Parameter2:
type: string
schemaVersion: 1.0
EOF

name = %[1]q
platform = "Linux"
version = "1.0.0"
}

resource "aws_imagebuilder_image_recipe" "test" {
component {
component_arn = aws_imagebuilder_component.test.arn

parameter {
name = "Parameter1"
value = "Value1"
}

parameter {
name = "Parameter2"
value = "Value2"
}
}

name = %[1]q
parent_image = "arn:${data.aws_partition.current.partition}:imagebuilder:${data.aws_region.current.name}:aws:image/amazon-linux-2-x86/x.x.x"
version = "1.0.0"
}
`, rName)
}

func testAccImageRecipeDescriptionConfig(rName string, description string) string {
return acctest.ConfigCompose(
testAccImageRecipeBaseConfig(rName),
Expand Down
20 changes: 19 additions & 1 deletion website/docs/r/imagebuilder_image_recipe.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ resource "aws_imagebuilder_image_recipe" "example" {

component {
component_arn = aws_imagebuilder_component.example.arn

parameter {
name = "Parameter1"
value = "Value1"
}

parameter {
name = "Parameter2"
value = "Value2"
}
}

name = "example"
Expand Down Expand Up @@ -74,9 +84,17 @@ The following arguments are optional:

### component

The following arguments are required:
The `component` block supports the following arguments:

* `component_arn` - (Required) Amazon Resource Name (ARN) of the Image Builder Component to associate.
* `parameter` - (Optional) Configuration block(s) for parameters to configure the component. Detailed below.

### parameter

The following arguments are required:

* `name` - (Required) The name of the component parameter.
* `value` - (Required) The value for the named component parameter.

## Attributes Reference

Expand Down