diff --git a/aws/resource_aws_api_gateway_rest_api.go b/aws/resource_aws_api_gateway_rest_api.go index fdf2debb539b..5922f7f82e5b 100644 --- a/aws/resource_aws_api_gateway_rest_api.go +++ b/aws/resource_aws_api_gateway_rest_api.go @@ -8,9 +8,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/apigateway" - "github.com/hashicorp/errwrap" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/structure" @@ -23,6 +21,9 @@ func resourceAwsApiGatewayRestApi() *schema.Resource { Read: resourceAwsApiGatewayRestApiRead, Update: resourceAwsApiGatewayRestApiUpdate, Delete: resourceAwsApiGatewayRestApiDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, Schema: map[string]*schema.Schema{ "name": { @@ -160,51 +161,43 @@ func resourceAwsApiGatewayRestApiCreate(d *schema.ResourceData, meta interface{} Body: []byte(body.(string)), }) if err != nil { - return errwrap.Wrapf("Error creating API Gateway specification: {{err}}", err) + return fmt.Errorf("error creating API Gateway specification: %s", err) } } - if err = resourceAwsApiGatewayRestApiRefreshResources(d, meta); err != nil { - return err - } - return resourceAwsApiGatewayRestApiRead(d, meta) } -func resourceAwsApiGatewayRestApiRefreshResources(d *schema.ResourceData, meta interface{}) error { +func resourceAwsApiGatewayRestApiRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).apigateway + log.Printf("[DEBUG] Reading API Gateway %s", d.Id()) - resp, err := conn.GetResources(&apigateway.GetResourcesInput{ + api, err := conn.GetRestApi(&apigateway.GetRestApiInput{ RestApiId: aws.String(d.Id()), }) - if err != nil { - return err + if isAWSErr(err, apigateway.ErrCodeNotFoundException, "") { + log.Printf("[WARN] API Gateway (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil } - - for _, item := range resp.Items { - if *item.Path == "/" { - d.Set("root_resource_id", item.Id) - break - } + if err != nil { + return fmt.Errorf("error reading API Gateway REST API (%s): %s", d.Id(), err) } - return nil -} - -func resourceAwsApiGatewayRestApiRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).apigateway - log.Printf("[DEBUG] Reading API Gateway %s", d.Id()) - - api, err := conn.GetRestApi(&apigateway.GetRestApiInput{ + getResourcesInput := &apigateway.GetResourcesInput{ RestApiId: aws.String(d.Id()), + } + err = conn.GetResourcesPages(getResourcesInput, func(page *apigateway.GetResourcesOutput, lastPage bool) bool { + for _, item := range page.Items { + if aws.StringValue(item.Path) == "/" { + d.Set("root_resource_id", item.Id) + return false + } + } + return !lastPage }) if err != nil { - if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NotFoundException" { - log.Printf("[WARN] API Gateway (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } - return err + return fmt.Errorf("error reading API Gateway REST API (%s) resources: %s", d.Id(), err) } d.Set("name", api.Name) @@ -359,7 +352,7 @@ func resourceAwsApiGatewayRestApiUpdate(d *schema.ResourceData, meta interface{} Body: []byte(body.(string)), }) if err != nil { - return errwrap.Wrapf("Error updating API Gateway specification: {{err}}", err) + return fmt.Errorf("error updating API Gateway specification: %s", err) } } } @@ -389,7 +382,7 @@ func resourceAwsApiGatewayRestApiDelete(d *schema.ResourceData, meta interface{} return nil } - if apigatewayErr, ok := err.(awserr.Error); ok && apigatewayErr.Code() == "NotFoundException" { + if isAWSErr(err, apigateway.ErrCodeNotFoundException, "") { return nil } diff --git a/aws/resource_aws_api_gateway_rest_api_test.go b/aws/resource_aws_api_gateway_rest_api_test.go index 3cf74165c668..7162062ca65d 100644 --- a/aws/resource_aws_api_gateway_rest_api_test.go +++ b/aws/resource_aws_api_gateway_rest_api_test.go @@ -106,6 +106,11 @@ func TestAccAWSAPIGatewayRestApi_basic(t *testing.T) { resource.TestCheckResourceAttr("aws_api_gateway_rest_api.test", "endpoint_configuration.#", "1"), ), }, + { + ResourceName: "aws_api_gateway_rest_api.test", + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccAWSAPIGatewayRestAPIUpdateConfig, @@ -154,6 +159,11 @@ func TestAccAWSAPIGatewayRestApi_EndpointConfiguration(t *testing.T) { resource.TestCheckResourceAttr("aws_api_gateway_rest_api.test", "endpoint_configuration.0.types.0", "REGIONAL"), ), }, + { + ResourceName: "aws_api_gateway_rest_api.test", + ImportState: true, + ImportStateVerify: true, + }, // For backwards compatibility, test removing endpoint_configuration, which should do nothing { Config: testAccAWSAPIGatewayRestAPIConfig_Name(rName), @@ -248,6 +258,11 @@ func TestAccAWSAPIGatewayRestApi_EndpointConfiguration_Private(t *testing.T) { resource.TestCheckResourceAttr("aws_api_gateway_rest_api.test", "endpoint_configuration.0.types.0", "PRIVATE"), ), }, + { + ResourceName: "aws_api_gateway_rest_api.test", + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -266,6 +281,11 @@ func TestAccAWSAPIGatewayRestApi_api_key_source(t *testing.T) { resource.TestCheckResourceAttr("aws_api_gateway_rest_api.test", "api_key_source", expectedAPIKeySource), ), }, + { + ResourceName: "aws_api_gateway_rest_api.test", + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccAWSAPIGatewayRestAPIConfigWithUpdateAPIKeySource, Check: resource.ComposeTestCheckFunc( @@ -296,6 +316,11 @@ func TestAccAWSAPIGatewayRestApi_policy(t *testing.T) { resource.TestCheckResourceAttr("aws_api_gateway_rest_api.test", "policy", expectedPolicyText), ), }, + { + ResourceName: "aws_api_gateway_rest_api.test", + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccAWSAPIGatewayRestAPIConfigUpdatePolicy, Check: resource.ComposeTestCheckFunc( @@ -333,7 +358,12 @@ func TestAccAWSAPIGatewayRestApi_openapi(t *testing.T) { resource.TestCheckNoResourceAttr("aws_api_gateway_rest_api.test", "binary_media_types"), ), }, - + { + ResourceName: "aws_api_gateway_rest_api.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"body"}, + }, { Config: testAccAWSAPIGatewayRestAPIUpdateConfigOpenAPI, Check: resource.ComposeTestCheckFunc( diff --git a/website/docs/r/api_gateway_rest_api.html.markdown b/website/docs/r/api_gateway_rest_api.html.markdown index 94e0b9ceb04f..2d1846c1b88e 100644 --- a/website/docs/r/api_gateway_rest_api.html.markdown +++ b/website/docs/r/api_gateway_rest_api.html.markdown @@ -71,3 +71,13 @@ In addition to all arguments above, the following attributes are exported: * `execution_arn` - The execution ARN part to be used in [`lambda_permission`](/docs/providers/aws/r/lambda_permission.html)'s `source_arn` when allowing API Gateway to invoke a Lambda function, e.g. `arn:aws:execute-api:eu-west-2:123456789012:z4675bid1j`, which can be concatenated with allowed stage, method and resource path. + +## Import + +`aws_api_gateway_rest_api` can be imported by using the REST API ID, e.g. + +``` +$ terraform import aws_api_gateway_rest_api.example 12345abcde +``` + +~> **NOTE:** Resource import does not currently support the `body` attribute.