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/aws_kms_key: Support policy lockout check bypass #18117

Merged
merged 36 commits into from
Aug 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d2195b5
Add policy lockout check bypass flag
tism Mar 16, 2021
10c4a11
Supply bypass flag when creating kms keys
tism Mar 16, 2021
a4a57d6
Supply bypass flag when updating kms keys
tism Mar 16, 2021
a0324c4
Add doco for bypass lockout check flag
tism Mar 16, 2021
7ae8f2f
Fix terraform formatting
tism Mar 16, 2021
9d45932
Add CHANGELOG entry.
ewbankkit Jul 17, 2021
ee55e96
Add internal KMS finder package.
ewbankkit Jul 17, 2021
ceed49d
r/aws_kms_key: Some waiter simplification.
ewbankkit Jul 17, 2021
e6ceb12
Add 'tfresource.RetryWhen'.
ewbankkit Jul 18, 2021
381e4d5
r/aws_kms_key: Simplify retry on Read.
ewbankkit Jul 18, 2021
352de32
Tweak 'RetryWhenNotFound'.
ewbankkit Jul 20, 2021
740579a
Tweak 'SetLastError'.
ewbankkit Jul 20, 2021
d0810a8
Add 'Context' versions of Retry functions.
ewbankkit Jul 21, 2021
bfe31d9
Add 'tfresource.WaitUntil'.
ewbankkit Jul 21, 2021
56a5697
Add 'updateKmsKeyRotationEnabled'.
ewbankkit Jul 21, 2021
5ad13b7
r/aws_kms_key: Tidy up eventual consistency checks.
ewbankkit Jul 21, 2021
121941b
r/aws_key: Use standard random name in acceptance tests.
ewbankkit Jul 22, 2021
518bee6
r/aws_kms_key: Wait for policy propagation.
ewbankkit Jul 22, 2021
b4a24fb
'bypass_policy_lockout_check' -> 'bypass_policy_lockout_safety_check'.
ewbankkit Jul 22, 2021
668db80
Add 'KeyValueTags.Equal'.
ewbankkit Jul 22, 2021
2452fd9
r/aws_kms_key: Wait for key-value tags propagation.
ewbankkit Jul 22, 2021
95bcab6
r/aws_kms_alias: Add and use 'finder.AliasByName'.
ewbankkit Jul 22, 2021
60b0404
r/aws_kms_alias: Add 'AliasARNToKeyARN'.
ewbankkit Jul 22, 2021
4130ed6
Error check.
ewbankkit Jul 22, 2021
6acc07e
Add 'KeyARNOrIDEqual'.
ewbankkit Jul 23, 2021
c449de0
r/aws_kms_alias: `name` and `name_prefix` are Computed.
ewbankkit Jul 23, 2021
97d68e6
d/aws_kms_alias: Use internal finder package.
ewbankkit Jul 27, 2021
4398730
r/aws_kms_external_key: Use internal packages.
ewbankkit Jul 27, 2021
c3bbe28
Add and use 'findKmsKey'.
ewbankkit Jul 27, 2021
2c10ec1
r/aws_kms_external_key: Add `bypass_policy_lockout_safety_check` argu…
ewbankkit Jul 27, 2021
3eb202a
r/aws_kms_key: Test completely empty configuration.
ewbankkit Jul 27, 2021
dfc1480
r/aws_kms_external_key: Add 'waiter.KeyMaterialImported'.
ewbankkit Jul 27, 2021
adcb59f
Add 'updateKmsKeyDescription' and 'waiter.KeyValidToPropagated'.
ewbankkit Jul 28, 2021
c111d91
Supply bypass flag when updating kms keys
tism Mar 16, 2021
bc1698d
Fix golangci-lint errors.
ewbankkit Aug 3, 2021
0b4a4c8
Fix awsproviderlint 'XAT001: missing ErrorCheck'.
ewbankkit Aug 3, 2021
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
7 changes: 7 additions & 0 deletions .changelog/18117.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_kms_key: Add `bypass_policy_lockout_safety_check` argument
```

```release-note:enhancement
resource/aws_kms_external_key: Add `bypass_policy_lockout_safety_check` argument
```
45 changes: 14 additions & 31 deletions aws/data_source_aws_kms_alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@ package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/kms"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/kms/finder"
)

func dataSourceAwsKmsAlias() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsKmsAliasRead,
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAwsKmsName,
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"target_key_arn": {
Type: schema.TypeString,
Computed: true,
Expand All @@ -36,27 +35,13 @@ func dataSourceAwsKmsAlias() *schema.Resource {

func dataSourceAwsKmsAliasRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).kmsconn
params := &kms.ListAliasesInput{}

target := d.Get("name")
var alias *kms.AliasListEntry
log.Printf("[DEBUG] Reading KMS Alias: %s", params)
err := conn.ListAliasesPages(params, func(page *kms.ListAliasesOutput, lastPage bool) bool {
for _, entity := range page.Aliases {
if aws.StringValue(entity.AliasName) == target {
alias = entity
return false
}
}
target := d.Get("name").(string)

return true
})
if err != nil {
return fmt.Errorf("Error fetch KMS alias list: %w", err)
}
alias, err := finder.AliasByName(conn, target)

if alias == nil {
return fmt.Errorf("No alias with name %q found in this region.", target)
if err != nil {
return fmt.Errorf("error reading KMS Alias (%s): %w", target, err)
}

d.SetId(aws.StringValue(alias.AliasArn))
Expand All @@ -73,16 +58,14 @@ func dataSourceAwsKmsAliasRead(d *schema.ResourceData, meta interface{}) error {
//
// https://docs.aws.amazon.com/kms/latest/APIReference/API_ListAliases.html

req := &kms.DescribeKeyInput{
KeyId: aws.String(target.(string)),
}
resp, err := conn.DescribeKey(req)
keyMetadata, err := finder.KeyByID(conn, target)

if err != nil {
return fmt.Errorf("Error calling KMS DescribeKey: %w", err)
return fmt.Errorf("error reading KMS Key (%s): %w", target, err)
}

d.Set("target_key_arn", resp.KeyMetadata.Arn)
d.Set("target_key_id", resp.KeyMetadata.KeyId)
d.Set("target_key_arn", keyMetadata.Arn)
d.Set("target_key_id", keyMetadata.KeyId)

return nil
}
44 changes: 16 additions & 28 deletions aws/data_source_aws_kms_alias_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import (
"github.com/aws/aws-sdk-go/service/kms"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccDataSourceAwsKmsAlias_AwsService(t *testing.T) {
name := "alias/aws/s3"
rName := "alias/aws/s3"
resourceName := "data.aws_kms_alias.test"

resource.ParallelTest(t, resource.TestCase{
Expand All @@ -21,11 +20,10 @@ func TestAccDataSourceAwsKmsAlias_AwsService(t *testing.T) {
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAwsKmsAlias_name(name),
Config: testAccDataSourceAwsKmsAliasConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccDataSourceAwsKmsAliasCheckExists(resourceName),
testAccCheckResourceAttrRegionalARN(resourceName, "arn", "kms", name),
resource.TestCheckResourceAttr(resourceName, "name", name),
testAccCheckResourceAttrRegionalARN(resourceName, "arn", "kms", rName),
resource.TestCheckResourceAttr(resourceName, "name", rName),
testAccMatchResourceAttrRegionalARN(resourceName, "target_key_arn", "kms", regexp.MustCompile(`key/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}`)),
resource.TestMatchResourceAttr(resourceName, "target_key_id", regexp.MustCompile("^[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}$")),
),
Expand All @@ -35,7 +33,7 @@ func TestAccDataSourceAwsKmsAlias_AwsService(t *testing.T) {
}

func TestAccDataSourceAwsKmsAlias_CMK(t *testing.T) {
rInt := acctest.RandInt()
rName := acctest.RandomWithPrefix("tf-acc-test")
aliasResourceName := "aws_kms_alias.test"
datasourceAliasResourceName := "data.aws_kms_alias.test"

Expand All @@ -45,9 +43,8 @@ func TestAccDataSourceAwsKmsAlias_CMK(t *testing.T) {
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAwsKmsAlias_CMK(rInt),
Config: testAccDataSourceAwsKmsAliasConfigCMK(rName),
Check: resource.ComposeTestCheckFunc(
testAccDataSourceAwsKmsAliasCheckExists(datasourceAliasResourceName),
resource.TestCheckResourceAttrPair(datasourceAliasResourceName, "arn", aliasResourceName, "arn"),
resource.TestCheckResourceAttrPair(datasourceAliasResourceName, "target_key_arn", aliasResourceName, "target_key_arn"),
resource.TestCheckResourceAttrPair(datasourceAliasResourceName, "target_key_id", aliasResourceName, "target_key_id"),
Expand All @@ -57,37 +54,28 @@ func TestAccDataSourceAwsKmsAlias_CMK(t *testing.T) {
})
}

func testAccDataSourceAwsKmsAliasCheckExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
_, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("root module has no resource called %s", name)
}

return nil
}
}

func testAccDataSourceAwsKmsAlias_name(name string) string {
func testAccDataSourceAwsKmsAliasConfig(rName string) string {
return fmt.Sprintf(`
data "aws_kms_alias" "test" {
name = "%s"
name = %[1]q
}
`, name)
`, rName)
}

func testAccDataSourceAwsKmsAlias_CMK(rInt int) string {
func testAccDataSourceAwsKmsAliasConfigCMK(rName string) string {
return fmt.Sprintf(`
resource "aws_kms_key" "test" {
description = "Terraform acc test"
description = %[1]q
deletion_window_in_days = 7
}

resource "aws_kms_alias" "test" {
name = "alias/tf-acc-key-alias-%d"
name = "alias/%[1]s"
target_key_id = aws_kms_key.test.key_id
}

%s
`, rInt, testAccDataSourceAwsKmsAlias_name("${aws_kms_alias.test.name}"))
data "aws_kms_alias" "test" {
name = aws_kms_alias.test.name
}
`, rName)
}
28 changes: 28 additions & 0 deletions aws/internal/keyvaluetags/key_value_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,34 @@ func (tags KeyValueTags) ContainsAll(target KeyValueTags) bool {
return true
}

// Equal returns whether or two sets of key-value tags are equal.
func (tags KeyValueTags) Equal(other KeyValueTags) bool {
if tags == nil && other == nil {
return true
}

if tags == nil || other == nil {
return false
}

if len(tags) != len(other) {
return false
}

for k, v := range tags {
o, ok := other[k]
if !ok {
return false
}

if !v.Equal(o) {
return false
}
}

return true
}

// Hash returns a stable hash value.
// The returned value may be negative (i.e. not suitable for a 'Set' function).
func (tags KeyValueTags) Hash() int {
Expand Down
126 changes: 126 additions & 0 deletions aws/internal/keyvaluetags/key_value_tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1824,6 +1824,132 @@ func TestKeyValueTagsContainsAll(t *testing.T) {
}
}

func TestKeyValueTagsEqual(t *testing.T) {
testCases := []struct {
name string
source KeyValueTags
target KeyValueTags
want bool
}{
{
name: "nil",
source: nil,
target: nil,
want: true,
},
{
name: "empty",
source: New(map[string]string{}),
target: New(map[string]string{}),
want: true,
},
{
name: "source_nil",
source: nil,
target: New(map[string]string{
"key1": "value1",
}),
want: false,
},
{
name: "source_empty",
source: New(map[string]string{}),
target: New(map[string]string{
"key1": "value1",
}),
want: false,
},
{
name: "target_nil",
source: New(map[string]string{
"key1": "value1",
}),
target: nil,
want: false,
},
{
name: "target_empty",
source: New(map[string]string{
"key1": "value1",
}),
target: New(map[string]string{}),
want: false,
},
{
name: "nil value matches",
source: New(map[string]*string{
"key1": nil,
}),
target: New(map[string]*string{
"key1": nil,
}),
want: true,
},
{
name: "exact_match",
source: New(map[string]string{
"key1": "value1",
"key2": "value2",
}),
target: New(map[string]string{
"key1": "value1",
"key2": "value2",
}),
want: true,
},
{
name: "source_contains_all",
source: New(map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}),
target: New(map[string]string{
"key1": "value1",
"key3": "value3",
}),
want: false,
},
{
name: "source_does_not_contain_all",
source: New(map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}),
target: New(map[string]string{
"key1": "value1",
"key4": "value4",
}),
want: false,
},
{
name: "target_value_neq",
source: New(map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}),
target: New(map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value4",
}),
want: false,
},
}

for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
got := testCase.source.Equal(testCase.target)

if got != testCase.want {
t.Errorf("unexpected Equal: %t", got)
}
})
}
}

func TestKeyValueTagsHash(t *testing.T) {
testCases := []struct {
name string
Expand Down
5 changes: 5 additions & 0 deletions aws/internal/naming/naming_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ func TestNamePrefixFromName(t *testing.T) {
Input: "terraform-20060102150405000000000001",
Expected: strPtr("terraform-"),
},
{
TestName: "KMS alias prefix",
Input: "alias/20210723150229087000000002",
Expected: strPtr("alias/"),
},
}

for _, testCase := range testCases {
Expand Down
Loading