Skip to content

Commit 8c59d08

Browse files
committed
Add aws_api_gateway_api_key resource
1 parent b4c99f1 commit 8c59d08

5 files changed

Lines changed: 393 additions & 0 deletions

File tree

builtin/providers/aws/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ func Provider() terraform.ResourceProvider {
115115
"aws_ami_copy": resourceAwsAmiCopy(),
116116
"aws_ami_from_instance": resourceAwsAmiFromInstance(),
117117
"aws_api_gateway_rest_api": resourceAwsApiGatewayRestApi(),
118+
"aws_api_gateway_api_key": resourceAwsApiGatewayApiKey(),
118119
"aws_api_gateway_model": resourceAwsApiGatewayModel(),
119120
"aws_api_gateway_resource": resourceAwsApiGatewayResource(),
120121
"aws_api_gateway_method": resourceAwsApiGatewayMethod(),
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package aws
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"time"
7+
8+
"github.com/aws/aws-sdk-go/aws"
9+
"github.com/aws/aws-sdk-go/aws/awserr"
10+
"github.com/aws/aws-sdk-go/service/apigateway"
11+
"github.com/hashicorp/terraform/helper/resource"
12+
"github.com/hashicorp/terraform/helper/schema"
13+
)
14+
15+
func resourceAwsApiGatewayApiKey() *schema.Resource {
16+
return &schema.Resource{
17+
Create: resourceAwsApiGatewayApiKeyCreate,
18+
Read: resourceAwsApiGatewayApiKeyRead,
19+
Update: resourceAwsApiGatewayApiKeyUpdate,
20+
Delete: resourceAwsApiGatewayApiKeyDelete,
21+
22+
Schema: map[string]*schema.Schema{
23+
"name": &schema.Schema{
24+
Type: schema.TypeString,
25+
Required: true,
26+
ForceNew: true,
27+
},
28+
29+
"description": &schema.Schema{
30+
Type: schema.TypeString,
31+
Required: true,
32+
},
33+
34+
"enabled": &schema.Schema{
35+
Type: schema.TypeBool,
36+
Optional: true,
37+
Default: true,
38+
},
39+
40+
"stage_key": &schema.Schema{
41+
Type: schema.TypeSet,
42+
Optional: true,
43+
Elem: &schema.Resource{
44+
Schema: map[string]*schema.Schema{
45+
"rest_api_id": &schema.Schema{
46+
Type: schema.TypeString,
47+
Required: true,
48+
},
49+
50+
"stage_name": &schema.Schema{
51+
Type: schema.TypeString,
52+
Required: true,
53+
},
54+
},
55+
},
56+
},
57+
},
58+
}
59+
}
60+
61+
func resourceAwsApiGatewayApiKeyCreate(d *schema.ResourceData, meta interface{}) error {
62+
conn := meta.(*AWSClient).apigateway
63+
log.Printf("[DEBUG] Creating API Gateway API Key")
64+
65+
apiKey, err := conn.CreateApiKey(&apigateway.CreateApiKeyInput{
66+
Name: aws.String(d.Get("name").(string)),
67+
Description: aws.String(d.Get("description").(string)),
68+
Enabled: aws.Bool(d.Get("enabled").(bool)),
69+
StageKeys: expandApiGatewayStageKeys(d),
70+
})
71+
if err != nil {
72+
return fmt.Errorf("Error creating API Gateway: %s", err)
73+
}
74+
75+
d.SetId(*apiKey.Id)
76+
77+
return resourceAwsApiGatewayApiKeyRead(d, meta)
78+
}
79+
80+
func resourceAwsApiGatewayApiKeyRead(d *schema.ResourceData, meta interface{}) error {
81+
conn := meta.(*AWSClient).apigateway
82+
log.Printf("[DEBUG] Reading API Gateway API Key: %s", d.Id())
83+
84+
apiKey, err := conn.GetApiKey(&apigateway.GetApiKeyInput{
85+
ApiKey: aws.String(d.Id()),
86+
})
87+
if err != nil {
88+
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NotFoundException" {
89+
d.SetId("")
90+
return nil
91+
}
92+
93+
return err
94+
}
95+
96+
d.Set("name", apiKey.Name)
97+
d.Set("description", apiKey.Description)
98+
d.Set("enabled", apiKey.Enabled)
99+
100+
return nil
101+
}
102+
103+
func resourceAwsApiGatewayApiKeyUpdateOperations(d *schema.ResourceData) []*apigateway.PatchOperation {
104+
operations := make([]*apigateway.PatchOperation, 0)
105+
if d.HasChange("enabled") {
106+
isEnabled := "false"
107+
if d.Get("enabled").(bool) {
108+
isEnabled = "true"
109+
}
110+
operations = append(operations, &apigateway.PatchOperation{
111+
Op: aws.String("replace"),
112+
Path: aws.String("/enabled"),
113+
Value: aws.String(isEnabled),
114+
})
115+
}
116+
117+
if d.HasChange("description") {
118+
operations = append(operations, &apigateway.PatchOperation{
119+
Op: aws.String("replace"),
120+
Path: aws.String("/description"),
121+
Value: aws.String(d.Get("description").(string)),
122+
})
123+
}
124+
125+
if d.HasChange("stage_key") {
126+
operations = append(operations, expandApiGatewayStageKeyOperations(d)...)
127+
}
128+
return operations
129+
}
130+
131+
func resourceAwsApiGatewayApiKeyUpdate(d *schema.ResourceData, meta interface{}) error {
132+
conn := meta.(*AWSClient).apigateway
133+
134+
log.Printf("[DEBUG] Updating API Gateway API Key: %s", d.Id())
135+
136+
_, err := conn.UpdateApiKey(&apigateway.UpdateApiKeyInput{
137+
ApiKey: aws.String(d.Id()),
138+
PatchOperations: resourceAwsApiGatewayApiKeyUpdateOperations(d),
139+
})
140+
if err != nil {
141+
return err
142+
}
143+
144+
return resourceAwsApiGatewayApiKeyRead(d, meta)
145+
}
146+
147+
func resourceAwsApiGatewayApiKeyDelete(d *schema.ResourceData, meta interface{}) error {
148+
conn := meta.(*AWSClient).apigateway
149+
log.Printf("[DEBUG] Deleting API Gateway API Key: %s", d.Id())
150+
151+
return resource.Retry(5*time.Minute, func() error {
152+
_, err := conn.DeleteApiKey(&apigateway.DeleteApiKeyInput{
153+
ApiKey: aws.String(d.Id()),
154+
})
155+
156+
if err == nil {
157+
return nil
158+
}
159+
160+
if apigatewayErr, ok := err.(awserr.Error); ok && apigatewayErr.Code() == "NotFoundException" {
161+
return nil
162+
}
163+
164+
return resource.RetryError{Err: err}
165+
})
166+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package aws
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"testing"
7+
8+
"github.com/aws/aws-sdk-go/aws"
9+
"github.com/aws/aws-sdk-go/aws/awserr"
10+
"github.com/aws/aws-sdk-go/service/apigateway"
11+
"github.com/hashicorp/terraform/helper/resource"
12+
"github.com/hashicorp/terraform/terraform"
13+
)
14+
15+
func TestAccAWSAPIGatewayApiKey_basic(t *testing.T) {
16+
var conf apigateway.ApiKey
17+
18+
resource.Test(t, resource.TestCase{
19+
PreCheck: func() { testAccPreCheck(t) },
20+
Providers: testAccProviders,
21+
CheckDestroy: testAccCheckAWSAPIGatewayApiKeyDestroy,
22+
Steps: []resource.TestStep{
23+
resource.TestStep{
24+
Config: testAccAWSAPIGatewayApiKeyConfig,
25+
Check: resource.ComposeTestCheckFunc(
26+
testAccCheckAWSAPIGatewayApiKeyExists("aws_api_gateway_api_key.test", &conf),
27+
testAccCheckAWSAPIGatewayApiKeyStageKeyAttribute(&conf),
28+
resource.TestCheckResourceAttr(
29+
"aws_api_gateway_api_key.test", "name", "foo"),
30+
resource.TestCheckResourceAttr(
31+
"aws_api_gateway_api_key.test", "description", "bar"),
32+
),
33+
},
34+
},
35+
})
36+
}
37+
38+
func testAccCheckAWSAPIGatewayApiKeyStageKeyAttribute(conf *apigateway.ApiKey) resource.TestCheckFunc {
39+
return func(s *terraform.State) error {
40+
if len(conf.StageKeys) != 1 {
41+
return fmt.Errorf("Expected one apikey. Got %d", len(conf.StageKeys))
42+
}
43+
if !strings.Contains(*conf.StageKeys[0], "test") {
44+
return fmt.Errorf("Expected apikey for test. Got %q", *conf.StageKeys[0])
45+
}
46+
return nil
47+
}
48+
}
49+
50+
func testAccCheckAWSAPIGatewayApiKeyExists(n string, res *apigateway.ApiKey) resource.TestCheckFunc {
51+
return func(s *terraform.State) error {
52+
rs, ok := s.RootModule().Resources[n]
53+
if !ok {
54+
return fmt.Errorf("Not found: %s", n)
55+
}
56+
57+
if rs.Primary.ID == "" {
58+
return fmt.Errorf("No API Gateway ApiKey ID is set")
59+
}
60+
61+
conn := testAccProvider.Meta().(*AWSClient).apigateway
62+
63+
req := &apigateway.GetApiKeyInput{
64+
ApiKey: aws.String(rs.Primary.ID),
65+
}
66+
describe, err := conn.GetApiKey(req)
67+
if err != nil {
68+
return err
69+
}
70+
71+
if *describe.Id != rs.Primary.ID {
72+
return fmt.Errorf("APIGateway ApiKey not found")
73+
}
74+
75+
*res = *describe
76+
77+
return nil
78+
}
79+
}
80+
81+
func testAccCheckAWSAPIGatewayApiKeyDestroy(s *terraform.State) error {
82+
conn := testAccProvider.Meta().(*AWSClient).apigateway
83+
84+
for _, rs := range s.RootModule().Resources {
85+
if rs.Type != "aws_api_gateway_api_key" {
86+
continue
87+
}
88+
89+
describe, err := conn.GetApiKeys(&apigateway.GetApiKeysInput{})
90+
91+
if err == nil {
92+
if len(describe.Items) != 0 &&
93+
*describe.Items[0].Id == rs.Primary.ID {
94+
return fmt.Errorf("API Gateway ApiKey still exists")
95+
}
96+
}
97+
98+
aws2err, ok := err.(awserr.Error)
99+
if !ok {
100+
return err
101+
}
102+
if aws2err.Code() != "NotFoundException" {
103+
return err
104+
}
105+
106+
return nil
107+
}
108+
109+
return nil
110+
}
111+
112+
const testAccAWSAPIGatewayApiKeyConfig = `
113+
resource "aws_api_gateway_rest_api" "test" {
114+
name = "test"
115+
}
116+
117+
resource "aws_api_gateway_resource" "test" {
118+
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
119+
parent_id = "${aws_api_gateway_rest_api.test.root_resource_id}"
120+
path_part = "test"
121+
}
122+
123+
resource "aws_api_gateway_method" "test" {
124+
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
125+
resource_id = "${aws_api_gateway_resource.test.id}"
126+
http_method = "GET"
127+
authorization = "NONE"
128+
}
129+
130+
resource "aws_api_gateway_method_response" "error" {
131+
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
132+
resource_id = "${aws_api_gateway_resource.test.id}"
133+
http_method = "${aws_api_gateway_method.test.http_method}"
134+
status_code = "400"
135+
}
136+
137+
resource "aws_api_gateway_integration" "test" {
138+
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
139+
resource_id = "${aws_api_gateway_resource.test.id}"
140+
http_method = "${aws_api_gateway_method.test.http_method}"
141+
142+
type = "HTTP"
143+
uri = "https://www.google.de"
144+
integration_http_method = "GET"
145+
}
146+
147+
resource "aws_api_gateway_integration_response" "test" {
148+
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
149+
resource_id = "${aws_api_gateway_resource.test.id}"
150+
http_method = "${aws_api_gateway_integration.test.http_method}"
151+
status_code = "${aws_api_gateway_method_response.error.status_code}"
152+
}
153+
154+
resource "aws_api_gateway_deployment" "test" {
155+
depends_on = ["aws_api_gateway_integration.test"]
156+
157+
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
158+
stage_name = "test"
159+
description = "This is a test"
160+
161+
variables = {
162+
"a" = "2"
163+
}
164+
}
165+
166+
resource "aws_api_gateway_api_key" "test" {
167+
name = "foo"
168+
description = "bar"
169+
enabled = true
170+
171+
stage_key {
172+
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
173+
stage_name = "${aws_api_gateway_deployment.test.stage_name}"
174+
}
175+
}
176+
`
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
layout: "aws"
3+
page_title: "AWS: aws_api_gateway_api_key"
4+
sidebar_current: "docs-aws-resource-api-gateway-api-key"
5+
description: |-
6+
Provides an API Gateway API Key.
7+
---
8+
9+
# aws\_api\_gateway\_api\_key
10+
11+
Provides an API Gateway API Key.
12+
13+
## Example Usage
14+
15+
```
16+
resource "aws_api_gateway_rest_api" "MyDemoAPI" {
17+
name = "MyDemoAPI"
18+
description = "This is my API for demonstration purposes"
19+
}
20+
21+
resource "aws_api_gateway_api_key" "MyDemoApiKey" {
22+
name = "demo"
23+
24+
stage_key {
25+
rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
26+
stage_name = "${aws_api_gateway_deployment.MyDemoDeployment.stage_name}"
27+
}
28+
}
29+
30+
resource "aws_api_gateway_deployment" "MyDemoDeployment" {
31+
rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
32+
stage_name = "test"
33+
}
34+
```
35+
36+
## Argument Reference
37+
38+
The following arguments are supported:
39+
40+
* `name` - (Required) Name of the API Gateway
41+
* `description` - (Optional) The API Gateway description
42+
* `stage_key` - (Optional) applicable API Gateway stages
43+
44+
Stage keys support the following:
45+
46+
* `rest_api_id` - (Required) The ID of the associated APIGateway Rest API.
47+
* `stage_name` - (Required) The name of the APIGateway stage.

0 commit comments

Comments
 (0)