Skip to content

Commit

Permalink
Merge pull request #19324 from suzuki-shunsuke/feat/appconfig_hosted_…
Browse files Browse the repository at this point in the history
…configuration_version

feat: support AppConfig Hosted Configuration Version
  • Loading branch information
anGie44 authored Jul 12, 2021
2 parents a96caa6 + dceee24 commit 0d5d425
Show file tree
Hide file tree
Showing 8 changed files with 410 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .changelog/19324.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_appconfig_hosted_configuration_version
```
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ func Provider() *schema.Provider {
"aws_appconfig_application": resourceAwsAppconfigApplication(),
"aws_appconfig_configuration_profile": resourceAwsAppconfigConfigurationProfile(),
"aws_appconfig_environment": resourceAwsAppconfigEnvironment(),
"aws_appconfig_hosted_configuration_version": resourceAwsAppconfigHostedConfigurationVersion(),
"aws_appmesh_gateway_route": resourceAwsAppmeshGatewayRoute(),
"aws_appmesh_mesh": resourceAwsAppmeshMesh(),
"aws_appmesh_route": resourceAwsAppmeshRoute(),
Expand Down
2 changes: 1 addition & 1 deletion aws/resource_aws_appconfig_configuration_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func resourceAwsAppconfigConfigurationProfileParseID(id string) (string, string,
parts := strings.Split(id, ":")

if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return "", "", fmt.Errorf("unexpected format of ID (%q), expected configurationProfileID:applicationID", id)
return "", "", fmt.Errorf("unexpected format of ID (%q), expected ConfigurationProfileID:ApplicationID", id)
}

return parts[0], parts[1], nil
Expand Down
2 changes: 1 addition & 1 deletion aws/resource_aws_appconfig_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func resourceAwsAppconfigEnvironmentParseID(id string) (string, string, error) {
parts := strings.Split(id, ":")

if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return "", "", fmt.Errorf("unexpected format of ID (%q), expected environmentID:applicationID", id)
return "", "", fmt.Errorf("unexpected format of ID (%q), expected EnvironmentID:ApplicationID", id)
}

return parts[0], parts[1], nil
Expand Down
190 changes: 190 additions & 0 deletions aws/resource_aws_appconfig_hosted_configuration_version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package aws

import (
"fmt"
"log"
"regexp"
"strconv"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/appconfig"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func resourceAwsAppconfigHostedConfigurationVersion() *schema.Resource {
return &schema.Resource{
Create: resourceAwsAppconfigHostedConfigurationVersionCreate,
Read: resourceAwsAppconfigHostedConfigurationVersionRead,
Delete: resourceAwsAppconfigHostedConfigurationVersionDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"application_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`[a-z0-9]{4,7}`), ""),
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"configuration_profile_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`[a-z0-9]{4,7}`), ""),
},
"content": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Sensitive: true,
},
"content_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 255),
},
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(0, 1024),
},
"version_number": {
Type: schema.TypeInt,
Computed: true,
},
},
}
}

func resourceAwsAppconfigHostedConfigurationVersionCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).appconfigconn

appID := d.Get("application_id").(string)
profileID := d.Get("configuration_profile_id").(string)

input := &appconfig.CreateHostedConfigurationVersionInput{
ApplicationId: aws.String(appID),
ConfigurationProfileId: aws.String(profileID),
Content: []byte(d.Get("content").(string)),
ContentType: aws.String(d.Get("content_type").(string)),
}

if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
}

output, err := conn.CreateHostedConfigurationVersion(input)

if err != nil {
return fmt.Errorf("error creating AppConfig HostedConfigurationVersion for Application (%s): %w", appID, err)
}

d.SetId(fmt.Sprintf("%s/%s/%d", aws.StringValue(output.ApplicationId), aws.StringValue(output.ConfigurationProfileId), aws.Int64Value(output.VersionNumber)))

return resourceAwsAppconfigHostedConfigurationVersionRead(d, meta)
}

func resourceAwsAppconfigHostedConfigurationVersionRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).appconfigconn

appID, confProfID, versionNumber, err := resourceAwsAppconfigHostedConfigurationVersionParseID(d.Id())

if err != nil {
return err
}

input := &appconfig.GetHostedConfigurationVersionInput{
ApplicationId: aws.String(appID),
ConfigurationProfileId: aws.String(confProfID),
VersionNumber: aws.Int64(int64(versionNumber)),
}

output, err := conn.GetHostedConfigurationVersion(input)

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) {
log.Printf("[WARN] Appconfig Hosted Configuration Version (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error getting AppConfig Hosted Configuration Version (%s): %w", d.Id(), err)
}

if output == nil {
return fmt.Errorf("error getting AppConfig Hosted Configuration Version (%s): empty response", d.Id())
}

d.Set("application_id", output.ApplicationId)
d.Set("configuration_profile_id", output.ConfigurationProfileId)
d.Set("content", string(output.Content))
d.Set("content_type", output.ContentType)
d.Set("description", output.Description)
d.Set("version_number", output.VersionNumber)

arn := arn.ARN{
AccountID: meta.(*AWSClient).accountid,
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Resource: fmt.Sprintf("application/%s/configurationprofile/%s/hostedconfigurationversion/%d", appID, confProfID, versionNumber),
Service: "appconfig",
}.String()

d.Set("arn", arn)

return nil
}

func resourceAwsAppconfigHostedConfigurationVersionDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).appconfigconn

appID, confProfID, versionNumber, err := resourceAwsAppconfigHostedConfigurationVersionParseID(d.Id())

if err != nil {
return err
}

input := &appconfig.DeleteHostedConfigurationVersionInput{
ApplicationId: aws.String(appID),
ConfigurationProfileId: aws.String(confProfID),
VersionNumber: aws.Int64(int64(versionNumber)),
}

_, err = conn.DeleteHostedConfigurationVersion(input)

if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) {
return nil
}

if err != nil {
return fmt.Errorf("error deleting Appconfig Hosted Configuration Version (%s): %w", d.Id(), err)
}

return nil
}

func resourceAwsAppconfigHostedConfigurationVersionParseID(id string) (string, string, int, error) {
parts := strings.Split(id, "/")

if len(parts) != 3 || parts[0] == "" || parts[1] == "" || parts[2] == "" {
return "", "", 0, fmt.Errorf("unexpected format of ID (%q), expected ApplicationID/ConfigurationProfileID/VersionNumber", id)
}

version, err := strconv.Atoi(parts[2])
if err != nil {
return "", "", 0, fmt.Errorf("error parsing Hosted Configuration Version version_number: %w", err)
}

return parts[0], parts[1], version, nil
}
161 changes: 161 additions & 0 deletions aws/resource_aws_appconfig_hosted_configuration_version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package aws

import (
"fmt"
"regexp"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/appconfig"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"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 TestAccAWSAppConfigHostedConfigurationVersion_basic(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_appconfig_hosted_configuration_version.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ErrorCheck: testAccErrorCheck(t, appconfig.EndpointsID),
Providers: testAccProviders,
CheckDestroy: testAccCheckAppConfigHostedConfigurationVersionDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAppConfigHostedConfigurationVersion(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAppConfigHostedConfigurationVersionExists(resourceName),
testAccMatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexp.MustCompile(`application/[a-z0-9]{4,7}/configurationprofile/[a-z0-9]{4,7}/hostedconfigurationversion/[0-9]+`)),
resource.TestCheckResourceAttrPair(resourceName, "application_id", "aws_appconfig_application.test", "id"),
resource.TestCheckResourceAttrPair(resourceName, "configuration_profile_id", "aws_appconfig_configuration_profile.test", "configuration_profile_id"),
resource.TestCheckResourceAttr(resourceName, "content", "{\"foo\":\"bar\"}"),
resource.TestCheckResourceAttr(resourceName, "content_type", "application/json"),
resource.TestCheckResourceAttr(resourceName, "description", rName),
resource.TestCheckResourceAttr(resourceName, "version_number", "1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSAppConfigHostedConfigurationVersion_disappears(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_appconfig_hosted_configuration_version.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ErrorCheck: testAccErrorCheck(t, appconfig.EndpointsID),
Providers: testAccProviders,
CheckDestroy: testAccCheckAppConfigHostedConfigurationVersionDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAppConfigHostedConfigurationVersion(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAppConfigHostedConfigurationVersionExists(resourceName),
testAccCheckResourceDisappears(testAccProvider, resourceAwsAppconfigHostedConfigurationVersion(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckAppConfigHostedConfigurationVersionDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).appconfigconn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_appconfig_hosted_configuration_version" {
continue
}

appID, confProfID, versionNumber, err := resourceAwsAppconfigHostedConfigurationVersionParseID(rs.Primary.ID)

if err != nil {
return err
}

input := &appconfig.GetHostedConfigurationVersionInput{
ApplicationId: aws.String(appID),
ConfigurationProfileId: aws.String(confProfID),
VersionNumber: aws.Int64(int64(versionNumber)),
}

output, err := conn.GetHostedConfigurationVersion(input)

if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) {
continue
}

if err != nil {
return fmt.Errorf("error reading AppConfig Hosted Configuration Version (%s): %w", rs.Primary.ID, err)
}

if output != nil {
return fmt.Errorf("AppConfig Hosted Configuration Version (%s) still exists", rs.Primary.ID)
}
}

return nil
}

func testAccCheckAWSAppConfigHostedConfigurationVersionExists(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)
}

if rs.Primary.ID == "" {
return fmt.Errorf("Resource (%s) ID not set", resourceName)
}

appID, confProfID, versionNumber, err := resourceAwsAppconfigHostedConfigurationVersionParseID(rs.Primary.ID)

if err != nil {
return err
}

conn := testAccProvider.Meta().(*AWSClient).appconfigconn

output, err := conn.GetHostedConfigurationVersion(&appconfig.GetHostedConfigurationVersionInput{
ApplicationId: aws.String(appID),
ConfigurationProfileId: aws.String(confProfID),
VersionNumber: aws.Int64(int64(versionNumber)),
})

if err != nil {
return fmt.Errorf("error reading AppConfig Hosted Configuration Version (%s): %w", rs.Primary.ID, err)
}

if output == nil {
return fmt.Errorf("AppConfig Hosted Configuration Version (%s) not found", rs.Primary.ID)
}

return nil
}
}

func testAccAWSAppConfigHostedConfigurationVersion(rName string) string {
return composeConfig(
testAccAWSAppConfigConfigurationProfileConfigName(rName),
fmt.Sprintf(`
resource "aws_appconfig_hosted_configuration_version" "test" {
application_id = aws_appconfig_application.test.id
configuration_profile_id = aws_appconfig_configuration_profile.test.configuration_profile_id
content_type = "application/json"
content = jsonencode({
foo = "bar"
})
description = %q
}
`, rName))
}
1 change: 1 addition & 0 deletions website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ for more information about connecting to alternate AWS endpoints or AWS compatib
- [`aws_appconfig_application` resource](/docs/providers/aws/r/appconfig_application.html)
- [`aws_appconfig_configuration_profile` resource](/docs/providers/aws/r/appconfig_configuration_profile.html)
- [`aws_appconfig_environment` resource](/docs/providers/aws/r/appconfig_environment.html)
- [`aws_appconfig_hosted_configuration_version` resource](/docs/providers/aws/r/appconfig_hosted_configuration_version.html)
- [`aws_athena_workgroup` resource](/docs/providers/aws/r/athena_workgroup.html)
- [`aws_budgets_budget` resource](/docs/providers/aws/r/budgets_budget.html)
- [`aws_codedeploy_app` resource](/docs/providers/aws/r/codedeploy_app.html)
Expand Down
Loading

0 comments on commit 0d5d425

Please sign in to comment.