diff --git a/aws/data_source_aws_imagebuilder_distribution_configuration.go b/aws/data_source_aws_imagebuilder_distribution_configuration.go new file mode 100644 index 00000000000..db3caa76f98 --- /dev/null +++ b/aws/data_source_aws_imagebuilder_distribution_configuration.go @@ -0,0 +1,144 @@ +package aws + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/imagebuilder" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func datasourceAwsImageBuilderDistributionConfiguration() *schema.Resource { + return &schema.Resource{ + Read: datasourceAwsImageBuilderDistributionConfigurationRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + "date_created": { + Type: schema.TypeString, + Computed: true, + }, + "date_updated": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "distribution": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ami_distribution_configuration": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ami_tags": tagsSchemaComputed(), + "description": { + Type: schema.TypeString, + Computed: true, + }, + "kms_key_id": { + Type: schema.TypeString, + Computed: true, + }, + "launch_permission": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user_groups": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "user_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "target_account_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "license_configuration_arns": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "region": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tagsSchemaComputed(), + }, + } +} + +func datasourceAwsImageBuilderDistributionConfigurationRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).imagebuilderconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + input := &imagebuilder.GetDistributionConfigurationInput{} + + if v, ok := d.GetOk("arn"); ok { + input.DistributionConfigurationArn = aws.String(v.(string)) + } + + output, err := conn.GetDistributionConfiguration(input) + + if err != nil { + return fmt.Errorf("error getting Image Builder Distribution Configuration (%s): %w", d.Id(), err) + } + + if output == nil || output.DistributionConfiguration == nil { + return fmt.Errorf("error getting Image Builder Distribution Configuration (%s): empty response", d.Id()) + } + + distributionConfiguration := output.DistributionConfiguration + + d.SetId(aws.StringValue(distributionConfiguration.Arn)) + d.Set("arn", distributionConfiguration.Arn) + d.Set("date_created", distributionConfiguration.DateCreated) + d.Set("date_updated", distributionConfiguration.DateUpdated) + d.Set("description", distributionConfiguration.Description) + d.Set("distribution", flattenImageBuilderDistributions(distributionConfiguration.Distributions)) + d.Set("name", distributionConfiguration.Name) + d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(distributionConfiguration.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()) + + return nil +} diff --git a/aws/data_source_aws_imagebuilder_distribution_configuration_test.go b/aws/data_source_aws_imagebuilder_distribution_configuration_test.go new file mode 100644 index 00000000000..d1cc2a64253 --- /dev/null +++ b/aws/data_source_aws_imagebuilder_distribution_configuration_test.go @@ -0,0 +1,53 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccAwsImageBuilderDistributionConfigurationDataSource_Arn(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + dataSourceName := "data.aws_imagebuilder_distribution_configuration.test" + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationDataSourceConfigArn(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "date_created", resourceName, "date_created"), + resource.TestCheckResourceAttrPair(dataSourceName, "date_updated", resourceName, "date_updated"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "distribution.#", resourceName, "distribution.#"), + resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", resourceName, "tags.%"), + ), + }, + }, + }) +} + +func testAccAwsImageBuilderDistributionConfigurationDataSourceConfigArn(rName string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + region = data.aws_region.current.name + } +} + +data "aws_imagebuilder_distribution_configuration" "test" { + arn = aws_imagebuilder_distribution_configuration.test.arn +} +`, rName) +} diff --git a/aws/provider.go b/aws/provider.go index c07039c8c2e..8fd45b6577b 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -267,6 +267,7 @@ func Provider() *schema.Provider { "aws_iam_server_certificate": dataSourceAwsIAMServerCertificate(), "aws_iam_user": dataSourceAwsIAMUser(), "aws_imagebuilder_component": dataSourceAwsImageBuilderComponent(), + "aws_imagebuilder_distribution_configuration": datasourceAwsImageBuilderDistributionConfiguration(), "aws_internet_gateway": dataSourceAwsInternetGateway(), "aws_iot_endpoint": dataSourceAwsIotEndpoint(), "aws_inspector_rules_packages": dataSourceAwsInspectorRulesPackages(), @@ -703,6 +704,7 @@ func Provider() *schema.Provider { "aws_iam_user": resourceAwsIamUser(), "aws_iam_user_login_profile": resourceAwsIamUserLoginProfile(), "aws_imagebuilder_component": resourceAwsImageBuilderComponent(), + "aws_imagebuilder_distribution_configuration": resourceAwsImageBuilderDistributionConfiguration(), "aws_inspector_assessment_target": resourceAWSInspectorAssessmentTarget(), "aws_inspector_assessment_template": resourceAWSInspectorAssessmentTemplate(), "aws_inspector_resource_group": resourceAWSInspectorResourceGroup(), diff --git a/aws/resource_aws_imagebuilder_distribution_configuration.go b/aws/resource_aws_imagebuilder_distribution_configuration.go new file mode 100644 index 00000000000..799487efede --- /dev/null +++ b/aws/resource_aws_imagebuilder_distribution_configuration.go @@ -0,0 +1,467 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/imagebuilder" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func resourceAwsImageBuilderDistributionConfiguration() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsImageBuilderDistributionConfigurationCreate, + Read: resourceAwsImageBuilderDistributionConfigurationRead, + Update: resourceAwsImageBuilderDistributionConfigurationUpdate, + Delete: resourceAwsImageBuilderDistributionConfigurationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "date_created": { + Type: schema.TypeString, + Computed: true, + }, + "date_updated": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 1024), + }, + "distribution": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ami_distribution_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ami_tags": tagsSchema(), + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 1024), + }, + "kms_key_id": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 1024), + }, + "launch_permission": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user_groups": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringLenBetween(1, 1024), + }, + }, + "user_ids": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validateAwsAccountId, + }, + MaxItems: 50, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.All( + validation.StringLenBetween(0, 127), + validation.StringMatch(regexp.MustCompile(`^[-_A-Za-z0-9{][-_A-Za-z0-9\s:{}]+[-_A-Za-z0-9}]$`), "must contain only alphanumeric characters, periods, underscores, and hyphens"), + ), + }, + "target_account_ids": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validateAwsAccountId, + }, + MaxItems: 50, + }, + }, + }, + }, + "license_configuration_arns": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validateArn, + }, + }, + "region": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(0, 1024), + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 126), + }, + "tags": tagsSchema(), + }, + } +} + +func resourceAwsImageBuilderDistributionConfigurationCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).imagebuilderconn + + input := &imagebuilder.CreateDistributionConfigurationInput{ + ClientToken: aws.String(resource.UniqueId()), + } + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("distribution"); ok && v.(*schema.Set).Len() > 0 { + input.Distributions = expandImageBuilderDistributions(v.(*schema.Set).List()) + } + + if v, ok := d.GetOk("name"); ok { + input.Name = aws.String(v.(string)) + } + + if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 { + input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().ImagebuilderTags() + } + + output, err := conn.CreateDistributionConfiguration(input) + + if err != nil { + return fmt.Errorf("error creating Image Builder Distribution Configuration: %w", err) + } + + if output == nil { + return fmt.Errorf("error creating Image Builder Distribution Configuration: empty response") + } + + d.SetId(aws.StringValue(output.DistributionConfigurationArn)) + + return resourceAwsImageBuilderDistributionConfigurationRead(d, meta) +} + +func resourceAwsImageBuilderDistributionConfigurationRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).imagebuilderconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + input := &imagebuilder.GetDistributionConfigurationInput{ + DistributionConfigurationArn: aws.String(d.Id()), + } + + output, err := conn.GetDistributionConfiguration(input) + + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, imagebuilder.ErrCodeResourceNotFoundException) { + log.Printf("[WARN] Image Builder Distribution Configuration (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error getting Image Builder Distribution Configuration (%s): %w", d.Id(), err) + } + + if output == nil || output.DistributionConfiguration == nil { + return fmt.Errorf("error getting Image Builder Distribution Configuration (%s): empty response", d.Id()) + } + + distributionConfiguration := output.DistributionConfiguration + + d.Set("arn", distributionConfiguration.Arn) + d.Set("date_created", distributionConfiguration.DateCreated) + d.Set("date_updated", distributionConfiguration.DateUpdated) + d.Set("description", distributionConfiguration.Description) + d.Set("distribution", flattenImageBuilderDistributions(distributionConfiguration.Distributions)) + d.Set("name", distributionConfiguration.Name) + d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(distributionConfiguration.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()) + + return nil +} + +func resourceAwsImageBuilderDistributionConfigurationUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).imagebuilderconn + + if d.HasChanges("description", "distribution") { + input := &imagebuilder.UpdateDistributionConfigurationInput{ + DistributionConfigurationArn: aws.String(d.Id()), + } + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("distribution"); ok && v.(*schema.Set).Len() > 0 { + input.Distributions = expandImageBuilderDistributions(v.(*schema.Set).List()) + } + + log.Printf("[DEBUG] UpdateDistributionConfiguration: %#v", input) + _, err := conn.UpdateDistributionConfiguration(input) + + if err != nil { + return fmt.Errorf("error updating Image Builder Distribution Configuration (%s): %w", d.Id(), err) + } + } + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.ImagebuilderUpdateTags(conn, d.Id(), o, n); err != nil { + return fmt.Errorf("error updating tags for Image Builder Distribution Configuration (%s): %w", d.Id(), err) + } + } + + return resourceAwsImageBuilderDistributionConfigurationRead(d, meta) +} + +func resourceAwsImageBuilderDistributionConfigurationDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).imagebuilderconn + + input := &imagebuilder.DeleteDistributionConfigurationInput{ + DistributionConfigurationArn: aws.String(d.Id()), + } + + _, err := conn.DeleteDistributionConfiguration(input) + + if tfawserr.ErrCodeEquals(err, imagebuilder.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Image Builder Distribution Config (%s): %w", d.Id(), err) + } + + return nil +} + +func expandImageBuilderAmiDistributionConfiguration(tfMap map[string]interface{}) *imagebuilder.AmiDistributionConfiguration { + if tfMap == nil { + return nil + } + + apiObject := &imagebuilder.AmiDistributionConfiguration{} + + if v, ok := tfMap["ami_tags"].(map[string]interface{}); ok && len(v) > 0 { + apiObject.AmiTags = stringMapToPointers(v) + } + + if v, ok := tfMap["description"].(string); ok && v != "" { + apiObject.Description = aws.String(v) + } + + if v, ok := tfMap["kms_key_id"].(string); ok && v != "" { + apiObject.KmsKeyId = aws.String(v) + } + + if v, ok := tfMap["launch_permission"].([]interface{}); ok && len(v) > 0 && v[0] != nil { + apiObject.LaunchPermission = expandImageBuilderLaunchPermissionConfiguration(v[0].(map[string]interface{})) + } + + if v, ok := tfMap["name"].(string); ok && v != "" { + apiObject.Name = aws.String(v) + } + + if v, ok := tfMap["target_account_ids"].(*schema.Set); ok && v.Len() > 0 { + apiObject.TargetAccountIds = expandStringSet(v) + } + + return apiObject +} + +func expandImageBuilderDistribution(tfMap map[string]interface{}) *imagebuilder.Distribution { + if tfMap == nil { + return nil + } + + apiObject := &imagebuilder.Distribution{} + + if v, ok := tfMap["ami_distribution_configuration"].([]interface{}); ok && len(v) > 0 && v[0] != nil { + apiObject.AmiDistributionConfiguration = expandImageBuilderAmiDistributionConfiguration(v[0].(map[string]interface{})) + } + + if v, ok := tfMap["license_configuration_arns"].(*schema.Set); ok && v.Len() > 0 { + apiObject.LicenseConfigurationArns = expandStringSet(v) + } + + if v, ok := tfMap["region"].(string); ok && v != "" { + apiObject.Region = aws.String(v) + } + + return apiObject +} + +func expandImageBuilderDistributions(tfList []interface{}) []*imagebuilder.Distribution { + if len(tfList) == 0 { + return nil + } + + var apiObjects []*imagebuilder.Distribution + + for _, tfMapRaw := range tfList { + tfMap, ok := tfMapRaw.(map[string]interface{}) + + if !ok { + continue + } + + apiObject := expandImageBuilderDistribution(tfMap) + + if apiObject == nil { + continue + } + + // Prevent error: InvalidParameter: 1 validation error(s) found. + // - missing required field, UpdateDistributionConfigurationInput.Distributions[0].Region + // Reference: https://github.com/hashicorp/terraform-plugin-sdk/issues/588 + if apiObject.Region == nil { + continue + } + + apiObjects = append(apiObjects, apiObject) + } + + return apiObjects +} + +func expandImageBuilderLaunchPermissionConfiguration(tfMap map[string]interface{}) *imagebuilder.LaunchPermissionConfiguration { + if tfMap == nil { + return nil + } + + apiObject := &imagebuilder.LaunchPermissionConfiguration{} + + if v, ok := tfMap["user_ids"].(*schema.Set); ok && v.Len() > 0 { + apiObject.UserIds = expandStringSet(v) + } + + if v, ok := tfMap["user_groups"].(*schema.Set); ok && v.Len() > 0 { + apiObject.UserGroups = expandStringSet(v) + } + + return apiObject +} + +func flattenImageBuilderAmiDistributionConfiguration(apiObject *imagebuilder.AmiDistributionConfiguration) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.AmiTags; v != nil { + tfMap["ami_tags"] = aws.StringValueMap(v) + } + + if v := apiObject.Description; v != nil { + tfMap["description"] = aws.StringValue(v) + } + + if v := apiObject.KmsKeyId; v != nil { + tfMap["kms_key_id"] = aws.StringValue(v) + } + + if v := apiObject.LaunchPermission; v != nil { + tfMap["launch_permission"] = []interface{}{flattenImageBuilderLaunchPermissionConfiguration(v)} + } + + if v := apiObject.Name; v != nil { + tfMap["name"] = aws.StringValue(v) + } + + if v := apiObject.TargetAccountIds; v != nil { + tfMap["target_account_ids"] = aws.StringValueSlice(v) + } + + return tfMap +} + +func flattenImageBuilderDistribution(apiObject *imagebuilder.Distribution) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.AmiDistributionConfiguration; v != nil { + tfMap["ami_distribution_configuration"] = []interface{}{flattenImageBuilderAmiDistributionConfiguration(v)} + } + + if v := apiObject.LicenseConfigurationArns; v != nil { + tfMap["license_configuration_arns"] = aws.StringValueSlice(v) + } + + if v := apiObject.Region; v != nil { + tfMap["region"] = aws.StringValue(v) + } + + return tfMap +} + +func flattenImageBuilderDistributions(apiObjects []*imagebuilder.Distribution) []interface{} { + if len(apiObjects) == 0 { + return nil + } + + var tfList []interface{} + + for _, apiObject := range apiObjects { + if apiObject == nil { + continue + } + + tfList = append(tfList, flattenImageBuilderDistribution(apiObject)) + } + + return tfList +} + +func flattenImageBuilderLaunchPermissionConfiguration(apiObject *imagebuilder.LaunchPermissionConfiguration) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.UserGroups; v != nil { + tfMap["user_groups"] = aws.StringValueSlice(v) + } + + if v := apiObject.UserIds; v != nil { + tfMap["user_ids"] = aws.StringValueSlice(v) + } + + return tfMap +} diff --git a/aws/resource_aws_imagebuilder_distribution_configuration_test.go b/aws/resource_aws_imagebuilder_distribution_configuration_test.go new file mode 100644 index 00000000000..1e079a70058 --- /dev/null +++ b/aws/resource_aws_imagebuilder_distribution_configuration_test.go @@ -0,0 +1,865 @@ +package aws + +import ( + "fmt" + "log" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/imagebuilder" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func init() { + resource.AddTestSweepers("aws_imagebuilder_distribution_configuration", &resource.Sweeper{ + Name: "aws_imagebuilder_distribution_configuration", + F: testSweepImageBuilderDistributionConfigurations, + }) +} + +func testSweepImageBuilderDistributionConfigurations(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).imagebuilderconn + + var sweeperErrs *multierror.Error + + input := &imagebuilder.ListDistributionConfigurationsInput{} + + err = conn.ListDistributionConfigurationsPages(input, func(page *imagebuilder.ListDistributionConfigurationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, distributionConfigurationSummary := range page.DistributionConfigurationSummaryList { + if distributionConfigurationSummary == nil { + continue + } + + arn := aws.StringValue(distributionConfigurationSummary.Arn) + + r := resourceAwsImageBuilderDistributionConfiguration() + d := r.Data(nil) + d.SetId(arn) + + err := r.Delete(d, client) + + if err != nil { + sweeperErr := fmt.Errorf("error deleting Image Builder Distribution Configuration (%s): %w", arn, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !lastPage + }) + + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Image Builder Distribution Configuration sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Image Builder Distribution Configurations: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccAwsImageBuilderDistributionConfiguration_basic(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigName(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "imagebuilder", fmt.Sprintf("distribution-configuration/%s", rName)), + testAccCheckResourceAttrRfc3339(resourceName, "date_created"), + resource.TestCheckResourceAttr(resourceName, "date_updated", ""), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_disappears(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigName(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceDisappears(testAccProvider, resourceAwsImageBuilderDistributionConfiguration(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Description(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDescription(rName, "description1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDescription(rName, "description2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccMultipleRegionPreCheck(t, 2) + }, + ProviderFactories: testAccProviderFactoriesMultipleRegion(nil, 2), + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistribution2(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_AmiDistributionConfiguration_AmiTags(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationAmiTags(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "distribution.*", map[string]string{ + "ami_distribution_configuration.#": "1", + "ami_distribution_configuration.0.ami_tags.%": "1", + "ami_distribution_configuration.0.ami_tags.key1": "value1", + }), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationAmiTags(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "distribution.*", map[string]string{ + "ami_distribution_configuration.#": "1", + "ami_distribution_configuration.0.ami_tags.%": "1", + "ami_distribution_configuration.0.ami_tags.key2": "value2", + }), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_AmiDistributionConfiguration_Description(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationDescription(rName, "description1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "distribution.*", map[string]string{ + "ami_distribution_configuration.#": "1", + "ami_distribution_configuration.0.description": "description1", + }), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationDescription(rName, "description2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "distribution.*", map[string]string{ + "ami_distribution_configuration.#": "1", + "ami_distribution_configuration.0.description": "description2", + }), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_AmiDistributionConfiguration_KmsKeyId(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + kmsKeyResourceName := "aws_kms_key.test" + kmsKeyResourceName2 := "aws_kms_key.test2" + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationKmsKeyId1(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "distribution.*.ami_distribution_configuration.0.kms_key_id", kmsKeyResourceName, "arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationKmsKeyId2(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "distribution.*.ami_distribution_configuration.0.kms_key_id", kmsKeyResourceName2, "arn"), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_AmiDistributionConfiguration_LaunchPermission_UserGroups(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationLaunchPermissionUserGroups(rName, "all"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "distribution.*.ami_distribution_configuration.0.launch_permission.0.user_groups.*", "all"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_AmiDistributionConfiguration_LaunchPermission_UserIds(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationLaunchPermissionUserIds(rName, "111111111111"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "distribution.*.ami_distribution_configuration.0.launch_permission.0.user_ids.*", "111111111111"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationLaunchPermissionUserIds(rName, "222222222222"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "distribution.*.ami_distribution_configuration.0.launch_permission.0.user_ids.*", "222222222222"), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_AmiDistributionConfiguration_Name(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationName(rName, "name1-{{ imagebuilder:buildDate }}"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "distribution.*", map[string]string{ + "ami_distribution_configuration.#": "1", + "ami_distribution_configuration.0.name": "name1-{{ imagebuilder:buildDate }}", + }), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationName(rName, "name2-{{ imagebuilder:buildDate }}"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "distribution.*", map[string]string{ + "ami_distribution_configuration.#": "1", + "ami_distribution_configuration.0.name": "name2-{{ imagebuilder:buildDate }}", + }), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_AmiDistributionConfiguration_TargetAccountIds(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationTargetAccountIds(rName, "111111111111"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "distribution.*.ami_distribution_configuration.0.target_account_ids.*", "111111111111"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationTargetAccountIds(rName, "222222222222"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "distribution.*.ami_distribution_configuration.0.target_account_ids.*", "222222222222"), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Distribution_LicenseConfigurationArns(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + licenseConfigurationResourceName := "aws_licensemanager_license_configuration.test" + licenseConfigurationResourceName2 := "aws_licensemanager_license_configuration.test2" + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionLicenseConfigurationArns1(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "distribution.*.license_configuration_arns.*", licenseConfigurationResourceName, "id"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigDistributionLicenseConfigurationArns2(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + testAccCheckResourceAttrRfc3339(resourceName, "date_updated"), + resource.TestCheckResourceAttr(resourceName, "distribution.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "distribution.*.license_configuration_arns.*", licenseConfigurationResourceName2, "id"), + ), + }, + }, + }) +} + +func TestAccAwsImageBuilderDistributionConfiguration_Tags(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_imagebuilder_distribution_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckAwsImageBuilderDistributionConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAwsImageBuilderDistributionConfigurationConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccCheckAwsImageBuilderDistributionConfigurationDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).imagebuilderconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_imagebuilder_distribution_configuration" { + continue + } + + input := &imagebuilder.GetDistributionConfigurationInput{ + DistributionConfigurationArn: aws.String(rs.Primary.ID), + } + + output, err := conn.GetDistributionConfiguration(input) + + if tfawserr.ErrCodeEquals(err, imagebuilder.ErrCodeResourceNotFoundException) { + continue + } + + if err != nil { + return fmt.Errorf("error getting Image Builder Distribution Configuration (%s): %w", rs.Primary.ID, err) + } + + if output != nil { + return fmt.Errorf("Image Builder Distribution Configuration (%s) still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckAwsImageBuilderDistributionConfigurationExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("resource not found: %s", resourceName) + } + + conn := testAccProvider.Meta().(*AWSClient).imagebuilderconn + + input := &imagebuilder.GetDistributionConfigurationInput{ + DistributionConfigurationArn: aws.String(rs.Primary.ID), + } + + _, err := conn.GetDistributionConfiguration(input) + + if err != nil { + return fmt.Errorf("error getting Image Builder Distribution Configuration (%s): %w", rs.Primary.ID, err) + } + + return nil + } +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDescription(rName string, description string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + description = %[2]q + name = %[1]q + + distribution { + region = data.aws_region.current.name + } +} +`, rName, description) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistribution2(rName string) string { + return composeConfig( + testAccMultipleRegionProviderConfig(2), + fmt.Sprintf(` +data "aws_region" "current" {} + +data "aws_region" "alternate" { + provider = awsalternate +} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + region = data.aws_region.current.name + } + + distribution { + region = data.aws_region.alternate.name + } +} +`, rName)) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationAmiTags(rName string, amiTagKey string, amiTagValue string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + ami_tags = { + %[2]q = %[3]q + } + } + + region = data.aws_region.current.name + } +} +`, rName, amiTagKey, amiTagValue) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationDescription(rName string, description string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + description = %[2]q + } + + region = data.aws_region.current.name + } +} +`, rName, description) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationKmsKeyId1(rName string) string { + return fmt.Sprintf(` +resource "aws_kms_key" "test" { + deletion_window_in_days = 7 +} + +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + kms_key_id = aws_kms_key.test.arn + } + + region = data.aws_region.current.name + } +} +`, rName) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationKmsKeyId2(rName string) string { + return fmt.Sprintf(` +resource "aws_kms_key" "test2" { + deletion_window_in_days = 7 +} + +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + kms_key_id = aws_kms_key.test2.arn + } + + region = data.aws_region.current.name + } +} +`, rName) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationLaunchPermissionUserGroups(rName string, userGroup string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + launch_permission { + user_groups = [%[2]q] + } + } + + region = data.aws_region.current.name + } +} +`, rName, userGroup) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationLaunchPermissionUserIds(rName string, userId string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + launch_permission { + user_ids = [%[2]q] + } + } + + region = data.aws_region.current.name + } +} +`, rName, userId) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationName(rName string, name string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + name = %[2]q + } + + region = data.aws_region.current.name + } +} +`, rName, name) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionAmiDistributionConfigurationTargetAccountIds(rName string, targetAccountId string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + ami_distribution_configuration { + target_account_ids = [%[2]q] + } + + region = data.aws_region.current.name + } +} +`, rName, targetAccountId) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionLicenseConfigurationArns1(rName string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_licensemanager_license_configuration" "test" { + name = %[1]q + license_counting_type = "Socket" +} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + license_configuration_arns = [aws_licensemanager_license_configuration.test.id] + region = data.aws_region.current.name + } +} +`, rName) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigDistributionLicenseConfigurationArns2(rName string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_licensemanager_license_configuration" "test2" { + name = %[1]q + license_counting_type = "Socket" +} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + license_configuration_arns = [aws_licensemanager_license_configuration.test2.id] + region = data.aws_region.current.name + } +} +`, rName) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigName(rName string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + region = data.aws_region.current.name + } +} +`, rName) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigTags1(rName string, tagKey1 string, tagValue1 string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + region = data.aws_region.current.name + } + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccAwsImageBuilderDistributionConfigurationConfigTags2(rName string, tagKey1 string, tagValue1 string, tagKey2 string, tagValue2 string) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_imagebuilder_distribution_configuration" "test" { + name = %[1]q + + distribution { + region = data.aws_region.current.name + } + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/website/docs/d/imagebuilder_distribution_configuration.html.markdown b/website/docs/d/imagebuilder_distribution_configuration.html.markdown new file mode 100644 index 00000000000..335a8d6a74d --- /dev/null +++ b/website/docs/d/imagebuilder_distribution_configuration.html.markdown @@ -0,0 +1,44 @@ +--- +subcategory: "Image Builder" +layout: "aws" +page_title: "AWS: aws_imagebuilder_distribution_configuration" +description: |- + Provides details about an Image Builder Distribution Configuration +--- + +# Data Source: aws_imagebuilder_distribution_configuration + +Provides details about an Image Builder Distribution Configuration. + +## Example Usage + +```hcl +data "aws_imagebuilder_distribution_configuration" "example" { + arn = "arn:aws:imagebuilder:us-west-2:aws:distribution-configuration/example" +} +``` + +## Argument Reference + +* `arn` - (Required) Amazon Resource Name (ARN) of the distribution configuration. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `date_created` - Date the distribution configuration was created. +* `date_updated` - Date the distribution configuration was updated. +* `description` - Description of the distribution configuration. +* `distribution` - Set of distributions. + * `ami_distribution_configuration` - Nested list of AMI distribution configuration. + * `ami_tags` - Key-value map of tags to apply to distributed AMI. + * `description` - Description to apply to distributed AMI. + * `kms_key_id` - Amazon Resource Name (ARN) of Key Management Service (KMS) Key to encrypt AMI. + * `launch_permission` - Nested list of EC2 launch permissions. + * `user_groups` - Set of EC2 launch permission user groups. + * `user_ids` - Set of AWS Account identifiers. + * `target_account_ids` - Set of target AWS Account identifiers. + * `license_configuration_arns` - Set of Amazon Resource Names (ARNs) of License Manager License Configurations. + * `region` - AWS Region of distribution. +* `name` - Name of the distribution configuration. +* `tags` - Key-value map of resource tags for the distribution configuration. diff --git a/website/docs/r/imagebuilder_distribution_configuration.html.markdown b/website/docs/r/imagebuilder_distribution_configuration.html.markdown new file mode 100644 index 00000000000..cef5821aeb7 --- /dev/null +++ b/website/docs/r/imagebuilder_distribution_configuration.html.markdown @@ -0,0 +1,93 @@ +--- +subcategory: "Image Builder" +layout: "aws" +page_title: "AWS: aws_imagebuilder_distribution_configuration" +description: |- + Manage an Image Builder Distribution Configuration +--- + +# Resource: aws_imagebuilder_distribution_configuration + +Manages an Image Builder Distribution Configuration. + +## Example Usage + +```hcl +resource "aws_imagebuilder_distribution_configuration" "example" { + name = "example" + + distribution { + ami_distribution_configuration { + ami_tags = { + CostCenter = "IT" + } + + name = "example-{{ imagebuilder:buildDate }}" + + launch_permission { + user_ids = ["123456789012"] + } + } + + region = "us-east-1" + } +} +``` + +## Argument Reference + +The following arguments are required: + +* `name` - (Required) Name of the distribution configuration. +* `distribution` - (Required) One or more configuration blocks with distribution settings. Detailed below. + +The following arguments are optional: + +* `description` - (Optional) Description of the distribution configuration. +* `kms_key_id` - (Optional) Amazon Resource Name (ARN) of the Key Management Service (KMS) Key used to encrypt the distribution configuration. +* `tags` - (Optional) Key-value map of resource tags for the distribution configuration. + +### distribution + +The following arguments are required: + +* `region` - (Required) AWS Region for the distribution. + +The following arguments are optional: + +* `ami_distribution_configuration` - (Optional) Configuration block with Amazon Machine Image (AMI) distribution settings. Detailed below. +* `license_configuration_arns` - (Optional) Set of Amazon Resource Names (ARNs) of License Manager License Configurations. + +### ami_distribution_configuration + +The following arguments are optional: + +* `ami_tags` - (Optional) Key-value map of tags to apply to the distributed AMI. +* `description` - (Optional) Description to apply to the distributed AMI. +* `kms_key_id` - (Optional) Amazon Resource Name (ARN) of the Key Management Service (KMS) Key to encrypt the distributed AMI. +* `launch_permission` - (Optional) Configuration block of EC2 launch permissions to apply to the distributed AMI. Detailed below. +* `name` - (Optional) Name to apply to the distributed AMI. +* `target_account_ids` - (Optional) Set of AWS Account identifiers to distribute the AMI. + +### launch_permission + +The following arguments are optional: + +* `user_groups` - (Optional) Set of EC2 launch permission user groups to assign. Use `all` to distribute a public AMI. +* `user_ids` - (Optional) Set of AWS Account identifiers to assign. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - (Required) Amazon Resource Name (ARN) of the distribution configuration. +* `date_created` - Date the distribution configuration was created. +* `date_updated` - Date the distribution configuration was updated. + +## Import + +`aws_imagebuilder_distribution_configurations` resources can be imported by using the Amazon Resource Name (ARN), e.g. + +``` +$ terraform import aws_imagebuilder_distribution_configuration.example arn:aws:imagebuilder:us-east-1:123456789012:distribution-configuration/example +```