diff --git a/.changelog/28030.txt b/.changelog/28030.txt new file mode 100644 index 00000000000..9f3e3bb9f41 --- /dev/null +++ b/.changelog/28030.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_api_gateway_deployment: Add importability +``` diff --git a/internal/service/apigateway/deployment.go b/internal/service/apigateway/deployment.go index 0cf2c0c3450..74e84587d06 100644 --- a/internal/service/apigateway/deployment.go +++ b/internal/service/apigateway/deployment.go @@ -1,8 +1,10 @@ package apigateway import ( + "context" "fmt" "log" + "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -22,6 +24,10 @@ func ResourceDeployment() *schema.Resource { Update: resourceDeploymentUpdate, Delete: resourceDeploymentDelete, + Importer: &schema.ResourceImporter{ + StateContext: resourceDeploymentImport, + }, + Schema: map[string]*schema.Schema{ "rest_api_id": { Type: schema.TypeString, @@ -221,3 +227,18 @@ func resourceDeploymentDelete(d *schema.ResourceData, meta interface{}) error { return nil } + +func resourceDeploymentImport(_ context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + idParts := strings.Split(d.Id(), "/") + if len(idParts) != 2 { + return nil, fmt.Errorf("Unexpected format of ID (%s), use: 'REST-API-ID/DEPLOYMENT-ID'", d.Id()) + } + + restApiID := idParts[0] + deploymentID := idParts[1] + + d.SetId(deploymentID) + d.Set("rest_api_id", restApiID) + + return []*schema.ResourceData{d}, nil +} diff --git a/internal/service/apigateway/deployment_test.go b/internal/service/apigateway/deployment_test.go index ade68071cc4..5d2955b2ebf 100644 --- a/internal/service/apigateway/deployment_test.go +++ b/internal/service/apigateway/deployment_test.go @@ -20,7 +20,6 @@ func TestAccAPIGatewayDeployment_basic(t *testing.T) { var deployment apigateway.Deployment resourceName := "aws_api_gateway_deployment.test" restApiResourceName := "aws_api_gateway_rest_api.test" - rName := sdkacctest.RandomWithPrefix("tf-acc-test-deployment") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckAPIGatewayTypeEDGE(t) }, @@ -29,19 +28,25 @@ func TestAccAPIGatewayDeployment_basic(t *testing.T) { CheckDestroy: testAccCheckDeploymentDestroy, Steps: []resource.TestStep{ { - Config: testAccDeploymentConfig_stageName(rName), + Config: testAccDeploymentConfig_required(), Check: resource.ComposeTestCheckFunc( testAccCheckDeploymentExists(resourceName, &deployment), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttr(resourceName, "description", ""), - acctest.MatchResourceAttrRegionalARN(resourceName, "execution_arn", "execute-api", regexp.MustCompile(fmt.Sprintf(".+/%s", rName))), - resource.TestMatchResourceAttr(resourceName, "invoke_url", regexp.MustCompile(fmt.Sprintf("https://.+\\.execute-api\\.%s.amazonaws\\.com/%s", acctest.Region(), rName))), + acctest.MatchResourceAttrRegionalARN(resourceName, "execution_arn", "execute-api", regexp.MustCompile(".+/")), + resource.TestMatchResourceAttr(resourceName, "invoke_url", regexp.MustCompile(fmt.Sprintf("https://.+\\.execute-api\\.%s.amazonaws\\.com/", acctest.Region()))), resource.TestCheckResourceAttrPair(resourceName, "rest_api_id", restApiResourceName, "id"), resource.TestCheckNoResourceAttr(resourceName, "stage_description"), - resource.TestCheckResourceAttr(resourceName, "stage_name", rName), + resource.TestCheckNoResourceAttr(resourceName, "stage_name"), resource.TestCheckNoResourceAttr(resourceName, "variables.%"), ), }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccDeploymentImportStateIdFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -184,6 +189,7 @@ func TestAccAPIGatewayDeployment_stageName(t *testing.T) { var deployment apigateway.Deployment var stage apigateway.Stage resourceName := "aws_api_gateway_deployment.test" + rName := sdkacctest.RandomWithPrefix("tf-acc-test-deployment") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckAPIGatewayTypeEDGE(t) }, @@ -192,17 +198,21 @@ func TestAccAPIGatewayDeployment_stageName(t *testing.T) { CheckDestroy: testAccCheckDeploymentDestroy, Steps: []resource.TestStep{ { - Config: testAccDeploymentConfig_stageName("test"), + Config: testAccDeploymentConfig_stageName(rName), Check: resource.ComposeTestCheckFunc( testAccCheckDeploymentExists(resourceName, &deployment), testAccCheckStageExists(resourceName, &stage), - resource.TestCheckResourceAttr(resourceName, "stage_name", "test"), + resource.TestCheckResourceAttr(resourceName, "stage_name", rName), + acctest.MatchResourceAttrRegionalARN(resourceName, "execution_arn", "execute-api", regexp.MustCompile(fmt.Sprintf(".+/%s", rName))), + resource.TestMatchResourceAttr(resourceName, "invoke_url", regexp.MustCompile(fmt.Sprintf("https://.+\\.execute-api\\.%s.amazonaws\\.com/%s", acctest.Region(), rName))), ), }, { Config: testAccDeploymentConfig_required(), Check: resource.ComposeTestCheckFunc( resource.TestCheckNoResourceAttr(resourceName, "stage_name"), + acctest.MatchResourceAttrRegionalARN(resourceName, "execution_arn", "execute-api", regexp.MustCompile(".+/")), + resource.TestMatchResourceAttr(resourceName, "invoke_url", regexp.MustCompile(fmt.Sprintf("https://.+\\.execute-api\\.%s.amazonaws\\.com/", acctest.Region()))), ), }, }, @@ -337,6 +347,17 @@ func testAccCheckDeploymentRecreated(i, j *apigateway.Deployment) resource.TestC } } +func testAccDeploymentImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not Found: %s", resourceName) + } + + return fmt.Sprintf("%s/%s", rs.Primary.Attributes["rest_api_id"], rs.Primary.ID), nil + } +} + func testAccDeploymentBaseConfig(uri string) string { return fmt.Sprintf(` resource "aws_api_gateway_rest_api" "test" { diff --git a/website/docs/r/api_gateway_deployment.html.markdown b/website/docs/r/api_gateway_deployment.html.markdown index 84a9881a84c..83a66aff0eb 100644 --- a/website/docs/r/api_gateway_deployment.html.markdown +++ b/website/docs/r/api_gateway_deployment.html.markdown @@ -148,3 +148,15 @@ In addition to all arguments above, the following attributes are exported: when allowing API Gateway to invoke a Lambda function, e.g., `arn:aws:execute-api:eu-west-2:123456789012:z4675bid1j/prod` * `created_date` - Creation date of the deployment + +## Import + +`aws_api_gateway_deployment` can be imported using `REST-API-ID/DEPLOYMENT-ID`, e.g., + +``` +$ terraform import aws_api_gateway_deployment.example aabbccddee/1122334 +``` + +The `stage_name`, `stage_description`, and `variables` arguments cannot be imported. Use the [`aws_api_gateway_stage` resource](api_gateway_stage.html) to import and manage stages. + +The `triggers` argument cannot be imported. \ No newline at end of file