Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/api_gateway_api_key - add customer key and make name updateable #33281

Merged
merged 8 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changelog/33281.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:enhancement
resource/aws_api_gateway_api_key: Add `customer_id` argument
```

```release-note:enhancement
resource/aws_api_gateway_api_key: Allow updating `name`
```

```release-note:enhancement
data-source/aws_api_gateway_api_key: Add `customer_id` attribute
```
67 changes: 40 additions & 27 deletions internal/service/apigateway/api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,34 +38,38 @@ func ResourceAPIKey() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"name": {
"arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Computed: true,
},
"created_date": {
Type: schema.TypeString,
Computed: true,
},
"customer_id": {
Type: schema.TypeString,
Optional: true,
},

"description": {
Type: schema.TypeString,
Optional: true,
Default: "Managed by Terraform",
},

"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},

"created_date": {
"last_updated_date": {
Type: schema.TypeString,
Computed: true,
},

"last_updated_date": {
"name": {
Type: schema.TypeString,
Computed: true,
Required: true,
},

names.AttrTags: tftags.TagsSchema(),
names.AttrTagsAll: tftags.TagsSchemaComputed(),
"value": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -74,12 +78,6 @@ func ResourceAPIKey() *schema.Resource {
Sensitive: true,
ValidateFunc: validation.StringLenBetween(20, 128),
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
names.AttrTags: tftags.TagsSchema(),
names.AttrTagsAll: tftags.TagsSchemaComputed(),
},

CustomizeDiff: verify.SetTagsDiff,
Expand All @@ -99,6 +97,10 @@ func resourceAPIKeyCreate(ctx context.Context, d *schema.ResourceData, meta inte
Value: aws.String(d.Get("value").(string)),
}

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

apiKey, err := conn.CreateApiKeyWithContext(ctx, input)

if err != nil {
Expand Down Expand Up @@ -135,25 +137,20 @@ func resourceAPIKeyRead(ctx context.Context, d *schema.ResourceData, meta interf
Resource: fmt.Sprintf("/apikeys/%s", d.Id()),
}.String()
d.Set("arn", arn)

d.Set("name", apiKey.Name)
d.Set("created_date", apiKey.CreatedDate.Format(time.RFC3339))
d.Set("customer_id", apiKey.CustomerId)
d.Set("description", apiKey.Description)
d.Set("enabled", apiKey.Enabled)
d.Set("last_updated_date", apiKey.LastUpdatedDate.Format(time.RFC3339))
d.Set("name", apiKey.Name)
d.Set("value", apiKey.Value)

if err := d.Set("created_date", apiKey.CreatedDate.Format(time.RFC3339)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting created_date: %s", err)
}

if err := d.Set("last_updated_date", apiKey.LastUpdatedDate.Format(time.RFC3339)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting last_updated_date: %s", err)
}

return diags
}

func resourceAPIKeyUpdateOperations(d *schema.ResourceData) []*apigateway.PatchOperation {
operations := make([]*apigateway.PatchOperation, 0)

if d.HasChange("enabled") {
isEnabled := "false"
if d.Get("enabled").(bool) {
Expand All @@ -174,6 +171,22 @@ func resourceAPIKeyUpdateOperations(d *schema.ResourceData) []*apigateway.PatchO
})
}

if d.HasChange("name") {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String(apigateway.OpReplace),
Path: aws.String("/name"),
Value: aws.String(d.Get("name").(string)),
})
}

if d.HasChange("customer_id") {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String(apigateway.OpReplace),
Path: aws.String("/customerId"),
Value: aws.String(d.Get("customer_id").(string)),
})
}

return operations
}

Expand Down
26 changes: 16 additions & 10 deletions internal/service/apigateway/api_key_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,42 @@ import (
func DataSourceAPIKey() *schema.Resource {
return &schema.Resource{
ReadWithoutTimeout: dataSourceAPIKeyRead,

Schema: map[string]*schema.Schema{
"id": {
"created_date": {
Type: schema.TypeString,
Required: true,
Computed: true,
},
"name": {
"customer_id": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"created_date": {
Type: schema.TypeString,
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"id": {
Type: schema.TypeString,
Required: true,
},
"last_updated_date": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
"name": {
Type: schema.TypeString,
Computed: true,
},
"tags": tftags.TagsSchemaComputed(),
"value": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
"tags": tftags.TagsSchemaComputed(),
},
}
}
Expand All @@ -67,12 +72,13 @@ func dataSourceAPIKeyRead(ctx context.Context, d *schema.ResourceData, meta inte
}

d.SetId(aws.StringValue(apiKey.Id))
d.Set("name", apiKey.Name)
d.Set("value", apiKey.Value)
d.Set("created_date", aws.TimeValue(apiKey.CreatedDate).Format(time.RFC3339))
d.Set("customer_id", apiKey.CustomerId)
d.Set("description", apiKey.Description)
d.Set("enabled", apiKey.Enabled)
d.Set("last_updated_date", aws.TimeValue(apiKey.LastUpdatedDate).Format(time.RFC3339))
d.Set("name", apiKey.Name)
d.Set("value", apiKey.Value)

if err := d.Set("tags", KeyValueTags(ctx, apiKey.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return sdkdiag.AppendErrorf(diags, "setting tags: %s", err)
Expand Down
15 changes: 8 additions & 7 deletions internal/service/apigateway/api_key_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,22 @@ func TestAccAPIGatewayAPIKeyDataSource_basic(t *testing.T) {
{
Config: testAccAPIKeyDataSourceConfig_basic(rName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(resourceName, "created_date", dataSourceName, "created_date"),
resource.TestCheckResourceAttrPair(resourceName, "customer_id", dataSourceName, "customer_id"),
resource.TestCheckResourceAttrPair(resourceName, "description", dataSourceName, "description"),
resource.TestCheckResourceAttrPair(resourceName, "enabled", dataSourceName, "enabled"),
resource.TestCheckResourceAttrPair(resourceName, "id", dataSourceName, "id"),
resource.TestCheckResourceAttrPair(resourceName, "last_updated_date", dataSourceName, "last_updated_date"),
resource.TestCheckResourceAttrPair(resourceName, "name", dataSourceName, "name"),
resource.TestCheckResourceAttrPair(resourceName, "tags.%", dataSourceName, "tags.%"),
resource.TestCheckResourceAttrPair(resourceName, "value", dataSourceName, "value"),
resource.TestCheckResourceAttrPair(resourceName, "enabled", dataSourceName, "enabled"),
resource.TestCheckResourceAttrPair(resourceName, "description", dataSourceName, "description"),
resource.TestCheckResourceAttrSet(dataSourceName, "last_updated_date"),
resource.TestCheckResourceAttrSet(dataSourceName, "created_date"),
resource.TestCheckResourceAttr(dataSourceName, "tags.%", "0"),
),
},
},
})
}

func testAccAPIKeyDataSourceConfig_basic(r string) string {
func testAccAPIKeyDataSourceConfig_basic(rName string) string {
return fmt.Sprintf(`
resource "aws_api_gateway_api_key" "test" {
name = %[1]q
Expand All @@ -50,5 +51,5 @@ resource "aws_api_gateway_api_key" "test" {
data "aws_api_gateway_api_key" "test" {
id = aws_api_gateway_api_key.test.id
}
`, r)
`, rName)
}
63 changes: 62 additions & 1 deletion internal/service/apigateway/api_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import (

func TestAccAPIGatewayAPIKey_basic(t *testing.T) {
ctx := acctest.Context(t)
var apiKey1 apigateway.ApiKey
var apiKey1, apiKey2 apigateway.ApiKey
resourceName := "aws_api_gateway_api_key.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
rNameUpdated := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
Expand All @@ -38,6 +39,7 @@ func TestAccAPIGatewayAPIKey_basic(t *testing.T) {
testAccCheckAPIKeyExists(ctx, resourceName, &apiKey1),
acctest.MatchResourceAttrRegionalARNNoAccount(resourceName, "arn", "apigateway", regexache.MustCompile(`/apikeys/+.`)),
resource.TestCheckResourceAttrSet(resourceName, "created_date"),
resource.TestCheckResourceAttr(resourceName, "customer_id", ""),
resource.TestCheckResourceAttr(resourceName, "description", "Managed by Terraform"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "name", rName),
Expand All @@ -50,6 +52,20 @@ func TestAccAPIGatewayAPIKey_basic(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAPIKeyConfig_basic(rNameUpdated),
Check: resource.ComposeTestCheckFunc(
testAccCheckAPIKeyExists(ctx, resourceName, &apiKey2),
acctest.MatchResourceAttrRegionalARNNoAccount(resourceName, "arn", "apigateway", regexache.MustCompile(`/apikeys/+.`)),
resource.TestCheckResourceAttrSet(resourceName, "created_date"),
resource.TestCheckResourceAttr(resourceName, "customer_id", ""),
resource.TestCheckResourceAttr(resourceName, "description", "Managed by Terraform"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "name", rNameUpdated),
resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"),
resource.TestCheckResourceAttrSet(resourceName, "value"),
),
},
},
})
}
Expand Down Expand Up @@ -100,6 +116,42 @@ func TestAccAPIGatewayAPIKey_tags(t *testing.T) {
})
}

func TestAccAPIGatewayAPIKey_customerID(t *testing.T) {
ctx := acctest.Context(t)
var apiKey1, apiKey2 apigateway.ApiKey
resourceName := "aws_api_gateway_api_key.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, apigateway.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAPIKeyDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccAPIKeyConfig_customerID(rName, "cid1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAPIKeyExists(ctx, resourceName, &apiKey1),
resource.TestCheckResourceAttr(resourceName, "customer_id", "cid1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAPIKeyConfig_customerID(rName, "cid2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAPIKeyExists(ctx, resourceName, &apiKey2),
testAccCheckAPIKeyNotRecreated(&apiKey1, &apiKey2),
resource.TestCheckResourceAttr(resourceName, "customer_id", "cid2"),
),
},
},
})
}

func TestAccAPIGatewayAPIKey_description(t *testing.T) {
ctx := acctest.Context(t)
var apiKey1, apiKey2 apigateway.ApiKey
Expand Down Expand Up @@ -318,6 +370,15 @@ resource "aws_api_gateway_api_key" "test" {
`, rName, tagKey1, tagValue1, tagKey2, tagValue2)
}

func testAccAPIKeyConfig_customerID(rName, customerID string) string {
return fmt.Sprintf(`
resource "aws_api_gateway_api_key" "test" {
customer_id = %[2]q
name = %[1]q
}
`, rName, customerID)
}

func testAccAPIKeyConfig_description(rName, description string) string {
return fmt.Sprintf(`
resource "aws_api_gateway_api_key" "test" {
Expand Down
1 change: 1 addition & 0 deletions website/docs/d/api_gateway_api_key.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ This data source exports the following attributes in addition to the arguments a
* `value` - Set to the value of the API Key.
* `created_date` - Date and time when the API Key was created.
* `last_updated_date` - Date and time when the API Key was last updated.
* `customer_id` - Amazon Web Services Marketplace customer identifier, when integrating with the Amazon Web Services SaaS Marketplace.
* `description` - Description of the API Key.
* `enabled` - Whether the API Key is enabled.
* `tags` - Map of tags for the resource.
10 changes: 5 additions & 5 deletions website/docs/r/api_gateway_api_key.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Provides an API Gateway API Key.
## Example Usage

```terraform
resource "aws_api_gateway_api_key" "MyDemoApiKey" {
name = "demo"
resource "aws_api_gateway_api_key" "example" {
name = "example"
}
```

Expand All @@ -25,6 +25,7 @@ resource "aws_api_gateway_api_key" "MyDemoApiKey" {
This resource supports the following arguments:

* `name` - (Required) Name of the API key.
* `customer_id` - (Required) An Amazon Web Services Marketplace customer identifier, when integrating with the Amazon Web Services SaaS Marketplace.
* `description` - (Optional) API key description. Defaults to "Managed by Terraform".
* `enabled` - (Optional) Whether the API key can be used by callers. Defaults to `true`.
* `value` - (Optional) Value of the API key. If specified, the value must be an alphanumeric string between 20 and 128 characters. If not specified, it will be automatically generated by AWS on creation.
Expand All @@ -37,7 +38,6 @@ This resource exports the following attributes in addition to the arguments abov
* `id` - ID of the API key
* `created_date` - Creation date of the API key
* `last_updated_date` - Last update date of the API key
* `value` - Value of the API key
* `arn` - ARN
* `tags_all` - Map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block).

Expand All @@ -47,13 +47,13 @@ In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashico

```terraform
import {
to = aws_api_gateway_api_key.my_demo_key
to = aws_api_gateway_api_key.example
id = "8bklk8bl1k3sB38D9B3l0enyWT8c09B30lkq0blk"
}
```

Using `terraform import`, import API Gateway Keys using the `id`. For example:

```console
% terraform import aws_api_gateway_api_key.my_demo_key 8bklk8bl1k3sB38D9B3l0enyWT8c09B30lkq0blk
% terraform import aws_api_gateway_api_key.example 8bklk8bl1k3sB38D9B3l0enyWT8c09B30lkq0blk
```