From ae2c7a5f0be01a269539cd145e00df316f90a10a Mon Sep 17 00:00:00 2001 From: Gauthier Wallet Date: Mon, 20 Mar 2017 14:54:14 +0100 Subject: [PATCH] provider/aws: Added Usage Plan Key resource (#12851) * provider/aws: Added Usage Plan Key resource * provider/aws: Added usage plan import documentation --- builtin/providers/aws/provider.go | 1 + ...resource_aws_api_gateway_usage_plan_key.go | 112 +++++++++ ...rce_aws_api_gateway_usage_plan_key_test.go | 232 ++++++++++++++++++ .../r/api_gateway_usage_plan.html.markdown | 8 + .../api_gateway_usage_plan_key.html.markdown | 59 +++++ website/source/layouts/aws.erb | 3 + 6 files changed, 415 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_api_gateway_usage_plan_key.go create mode 100644 builtin/providers/aws/resource_aws_api_gateway_usage_plan_key_test.go create mode 100644 website/source/docs/providers/aws/r/api_gateway_usage_plan_key.html.markdown diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 8b9be43b9..744eb21ad 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -220,6 +220,7 @@ func Provider() terraform.ResourceProvider { "aws_api_gateway_resource": resourceAwsApiGatewayResource(), "aws_api_gateway_rest_api": resourceAwsApiGatewayRestApi(), "aws_api_gateway_usage_plan": resourceAwsApiGatewayUsagePlan(), + "aws_api_gateway_usage_plan_key": resourceAwsApiGatewayUsagePlanKey(), "aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(), "aws_appautoscaling_target": resourceAwsAppautoscalingTarget(), "aws_appautoscaling_policy": resourceAwsAppautoscalingPolicy(), diff --git a/builtin/providers/aws/resource_aws_api_gateway_usage_plan_key.go b/builtin/providers/aws/resource_aws_api_gateway_usage_plan_key.go new file mode 100644 index 000000000..75e7bbefd --- /dev/null +++ b/builtin/providers/aws/resource_aws_api_gateway_usage_plan_key.go @@ -0,0 +1,112 @@ +package aws + +import ( + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/apigateway" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsApiGatewayUsagePlanKey() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsApiGatewayUsagePlanKeyCreate, + Read: resourceAwsApiGatewayUsagePlanKeyRead, + Delete: resourceAwsApiGatewayUsagePlanKeyDelete, + + Schema: map[string]*schema.Schema{ + "key_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "key_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "usage_plan_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "name": { + Type: schema.TypeString, + Computed: true, + }, + + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceAwsApiGatewayUsagePlanKeyCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).apigateway + log.Print("[DEBUG] Creating API Gateway Usage Plan Key") + + params := &apigateway.CreateUsagePlanKeyInput{ + KeyId: aws.String(d.Get("key_id").(string)), + KeyType: aws.String(d.Get("key_type").(string)), + UsagePlanId: aws.String(d.Get("usage_plan_id").(string)), + } + + up, err := conn.CreateUsagePlanKey(params) + if err != nil { + return fmt.Errorf("Error creating API Gateway Usage Plan Key: %s", err) + } + + d.SetId(*up.Id) + + return resourceAwsApiGatewayUsagePlanKeyRead(d, meta) +} + +func resourceAwsApiGatewayUsagePlanKeyRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).apigateway + log.Printf("[DEBUG] Reading API Gateway Usage Plan Key: %s", d.Id()) + + up, err := conn.GetUsagePlanKey(&apigateway.GetUsagePlanKeyInput{ + UsagePlanId: aws.String(d.Get("usage_plan_id").(string)), + KeyId: aws.String(d.Get("key_id").(string)), + }) + if err != nil { + if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NotFoundException" { + d.SetId("") + return nil + } + return err + } + + d.Set("name", up.Name) + d.Set("value", up.Value) + + return nil +} + +func resourceAwsApiGatewayUsagePlanKeyDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).apigateway + + log.Printf("[DEBUG] Deleting API Gateway Usage Plan Key: %s", d.Id()) + + return resource.Retry(5*time.Minute, func() *resource.RetryError { + _, err := conn.DeleteUsagePlanKey(&apigateway.DeleteUsagePlanKeyInput{ + UsagePlanId: aws.String(d.Get("usage_plan_id").(string)), + KeyId: aws.String(d.Get("key_id").(string)), + }) + + if err == nil { + return nil + } + + return resource.NonRetryableError(err) + }) +} diff --git a/builtin/providers/aws/resource_aws_api_gateway_usage_plan_key_test.go b/builtin/providers/aws/resource_aws_api_gateway_usage_plan_key_test.go new file mode 100644 index 000000000..608a88fd2 --- /dev/null +++ b/builtin/providers/aws/resource_aws_api_gateway_usage_plan_key_test.go @@ -0,0 +1,232 @@ +package aws + +import ( + "fmt" + "log" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/apigateway" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSAPIGatewayUsagePlanKey_basic(t *testing.T) { + var conf apigateway.UsagePlanKey + name := acctest.RandString(10) + updatedName := acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSApiGatewayUsagePlanKeyBasicConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAPIGatewayUsagePlanKeyExists("aws_api_gateway_usage_plan_key.main", &conf), + resource.TestCheckResourceAttr("aws_api_gateway_usage_plan_key.main", "key_type", "API_KEY"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "key_id"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "key_type"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "usage_plan_id"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "name"), + resource.TestCheckResourceAttr("aws_api_gateway_usage_plan_key.main", "value", ""), + ), + }, + { + Config: testAccAWSApiGatewayUsagePlanKeyBasicUpdatedConfig(updatedName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAPIGatewayUsagePlanKeyExists("aws_api_gateway_usage_plan_key.main", &conf), + resource.TestCheckResourceAttr("aws_api_gateway_usage_plan_key.main", "key_type", "API_KEY"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "key_id"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "key_type"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "usage_plan_id"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "name"), + resource.TestCheckResourceAttr("aws_api_gateway_usage_plan_key.main", "value", ""), + ), + }, + { + Config: testAccAWSApiGatewayUsagePlanKeyBasicConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAPIGatewayUsagePlanKeyExists("aws_api_gateway_usage_plan_key.main", &conf), + resource.TestCheckResourceAttr("aws_api_gateway_usage_plan_key.main", "key_type", "API_KEY"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "key_id"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "key_type"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "usage_plan_id"), + resource.TestCheckResourceAttrSet("aws_api_gateway_usage_plan_key.main", "name"), + resource.TestCheckResourceAttr("aws_api_gateway_usage_plan_key.main", "value", ""), + ), + }, + }, + }) +} + +func testAccCheckAWSAPIGatewayUsagePlanKeyExists(n string, res *apigateway.UsagePlanKey) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No API Gateway Usage Plan Key ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).apigateway + + req := &apigateway.GetUsagePlanKeyInput{ + UsagePlanId: aws.String(rs.Primary.Attributes["usage_plan_id"]), + KeyId: aws.String(rs.Primary.Attributes["key_id"]), + } + up, err := conn.GetUsagePlanKey(req) + if err != nil { + return err + } + + log.Printf("[DEBUG] Reading API Gateway Usage Plan Key: %#v", up) + + if *up.Id != rs.Primary.ID { + return fmt.Errorf("API Gateway Usage Plan Key not found") + } + + *res = *up + + return nil + } +} + +func testAccCheckAWSAPIGatewayUsagePlanKeyDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).apigateway + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_api_gateway_usage_plan_key" { + continue + } + + req := &apigateway.GetUsagePlanKeyInput{ + UsagePlanId: aws.String(rs.Primary.ID), + KeyId: aws.String(rs.Primary.Attributes["key_id"]), + } + describe, err := conn.GetUsagePlanKey(req) + + if err == nil { + if describe.Id != nil && *describe.Id == rs.Primary.ID { + return fmt.Errorf("API Gateway Usage Plan Key still exists") + } + } + + aws2err, ok := err.(awserr.Error) + if !ok { + return err + } + if aws2err.Code() != "NotFoundException" { + return err + } + + return nil + } + + return nil +} + +const testAccAWSAPIGatewayUsagePlanKeyConfig = ` +resource "aws_api_gateway_rest_api" "test" { + name = "test" +} + +resource "aws_api_gateway_resource" "test" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + parent_id = "${aws_api_gateway_rest_api.test.root_resource_id}" + path_part = "test" +} + +resource "aws_api_gateway_method" "test" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_resource.test.id}" + http_method = "GET" + authorization = "NONE" +} + +resource "aws_api_gateway_method_response" "error" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_resource.test.id}" + http_method = "${aws_api_gateway_method.test.http_method}" + status_code = "400" +} + +resource "aws_api_gateway_integration" "test" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_resource.test.id}" + http_method = "${aws_api_gateway_method.test.http_method}" + + type = "HTTP" + uri = "https://www.google.de" + integration_http_method = "GET" +} + +resource "aws_api_gateway_integration_response" "test" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_resource.test.id}" + http_method = "${aws_api_gateway_integration.test.http_method}" + status_code = "${aws_api_gateway_method_response.error.status_code}" +} + +resource "aws_api_gateway_deployment" "test" { + depends_on = ["aws_api_gateway_integration.test"] + + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + stage_name = "test" + description = "This is a test" + + variables = { + "a" = "2" + } +} + +resource "aws_api_gateway_deployment" "foo" { + depends_on = ["aws_api_gateway_integration.test"] + + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + stage_name = "foo" + description = "This is a prod stage" +} + +resource "aws_api_gateway_usage_plan" "main" { + name = "%s" +} + +resource "aws_api_gateway_usage_plan" "secondary" { + name = "secondary-%s" +} + +resource "aws_api_gateway_api_key" "mykey" { + name = "demo-%s" + + stage_key { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + stage_name = "${aws_api_gateway_deployment.foo.stage_name}" + } +} +` + +func testAccAWSApiGatewayUsagePlanKeyBasicConfig(rName string) string { + return fmt.Sprintf(testAccAWSAPIGatewayUsagePlanKeyConfig+` +resource "aws_api_gateway_usage_plan_key" "main" { + key_id = "${aws_api_gateway_api_key.mykey.id}" + key_type = "API_KEY" + usage_plan_id = "${aws_api_gateway_usage_plan.main.id}" +} +`, rName, rName, rName) +} + +func testAccAWSApiGatewayUsagePlanKeyBasicUpdatedConfig(rName string) string { + return fmt.Sprintf(testAccAWSAPIGatewayUsagePlanKeyConfig+` +resource "aws_api_gateway_usage_plan_key" "main" { + key_id = "${aws_api_gateway_api_key.mykey.id}" + key_type = "API_KEY" + usage_plan_id = "${aws_api_gateway_usage_plan.secondary.id}" +} +`, rName, rName, rName) +} diff --git a/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown b/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown index 70f75ca3a..46fa85d8e 100644 --- a/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown +++ b/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown @@ -97,3 +97,11 @@ The following attributes are exported: * `quota_settings` - The quota of the usage plan. * `throttle_settings` - The throttling limits of the usage plan. * `product_code` - The AWS Markeplace product identifier to associate with the usage plan as a SaaS product on AWS Marketplace. + +## Import + +AWS API Gateway Usage Plan can be imported using the `id`, e.g. + +``` +$ terraform import aws_api_gateway_usage_plan.myusageplan +``` diff --git a/website/source/docs/providers/aws/r/api_gateway_usage_plan_key.html.markdown b/website/source/docs/providers/aws/r/api_gateway_usage_plan_key.html.markdown new file mode 100644 index 000000000..0a4293eea --- /dev/null +++ b/website/source/docs/providers/aws/r/api_gateway_usage_plan_key.html.markdown @@ -0,0 +1,59 @@ +--- +layout: "aws" +page_title: "AWS: aws_api_gateway_usage_plan_key" +sidebar_current: "docs-aws-resource-api-gateway-usage-plan-key" +description: |- + Provides an API Gateway Usage Plan Key. +--- + +# aws\_api\_usage\_plan\_key + +Provides an API Gateway Usage Plan Key. + +## Example Usage + +``` +resource "aws_api_gateway_rest_api" "test" { + name = "MyDemoAPI" +} + +... + +resource "aws_api_gateway_usage_plan" "myusageplan" { + name = "my_usage_plan" +} + +resource "aws_api_gateway_api_key" "mykey" { + name = "my_key" + + stage_key { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + stage_name = "${aws_api_gateway_deployment.foo.stage_name}" + } +} + +resource "aws_api_gateway_usage_plan_key" "main" { + key_id = "${aws_api_gateway_api_key.mykey.id}" + key_type = "API_KEY" + usage_plan_id = "${aws_api_gateway_usage_plan.myusageplan.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `key_id` - (Required) The identifier of the API key resource. +* `key_type` - (Required) The type of the API key resource. Currently, the valid key type is API_KEY. +* `usage_plan_id` - (Required) The Id of the usage plan resource representing to associate the key to. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Id of a usage plan key. +* `key_id` - The type of a usage plan key. Currently, the valid key type is API_KEY. +* `key_type` - The ID of the API resource +* `usage_plan_id` - The ID of the API resource +* `name` - The name of a usage plan key. +* `value` - The value of a usage plan key. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index 8bcced9aa..73656110a 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -182,6 +182,9 @@ > aws_api_gateway_usage_plan + > + aws_api_gateway_usage_plan_key +