-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
New Data Source: aws_kms_key #2224
Changes from 16 commits
90c1c22
fdc3867
68ed0d7
285d3d6
14e39a1
07cc945
ea8d786
7ad8692
c9efdad
d4223a8
8a6cb04
cd7b03d
7c572c3
55800a4
1195057
edc5096
656d814
e28ea81
7b9f50d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/kms" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func dataSourceAwsKmsKey() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceAwsKmsKeyRead, | ||
Schema: map[string]*schema.Schema{ | ||
"key_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validateKmsKey, | ||
}, | ||
"grant_tokens": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
"arn": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"aws_account_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"creation_date": { | ||
Type: schema.TypeFloat, | ||
Computed: true, | ||
}, | ||
"deletion_date": { | ||
Type: schema.TypeFloat, | ||
Computed: true, | ||
}, | ||
"description": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"enabled": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
}, | ||
"expiration_model": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"key_manager": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"key_state": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"key_usage": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"origin": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"valid_to": { | ||
Type: schema.TypeFloat, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceAwsKmsKeyRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).kmsconn | ||
keyId, keyIdOk := d.GetOk("key_id") | ||
if !keyIdOk { | ||
return fmt.Errorf("key_id value is missing") | ||
} | ||
var grantTokens []*string | ||
if v, ok := d.GetOk("grant_tokens"); ok { | ||
for _, token := range v.([]interface{}) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe you can simplify this to just |
||
grantTokens = append(grantTokens, aws.String(token.(string))) | ||
} | ||
} | ||
input := &kms.DescribeKeyInput{ | ||
KeyId: aws.String(keyId.(string)), | ||
GrantTokens: grantTokens, | ||
} | ||
output, err := conn.DescribeKey(input) | ||
if err != nil { | ||
return fmt.Errorf("error while describing key [%s]: %s", keyId, err) | ||
} | ||
d.SetId(aws.StringValue(output.KeyMetadata.KeyId)) | ||
d.Set("arn", output.KeyMetadata.Arn) | ||
d.Set("aws_account_id", output.KeyMetadata.AWSAccountId) | ||
d.Set("creation_date", output.KeyMetadata.CreationDate) | ||
d.Set("deletion_date", output.KeyMetadata.DeletionDate) | ||
d.Set("description", output.KeyMetadata.Description) | ||
d.Set("enabled", output.KeyMetadata.Enabled) | ||
d.Set("expiration_model", output.KeyMetadata.ExpirationModel) | ||
d.Set("key_manager", output.KeyMetadata.KeyManager) | ||
d.Set("key_state", output.KeyMetadata.KeyState) | ||
d.Set("key_usage", output.KeyMetadata.KeyUsage) | ||
d.Set("origin", output.KeyMetadata.Origin) | ||
d.Set("valid_to", output.KeyMetadata.ValidTo) | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccDataSourceAwsKmsKey(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: can you append |
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccDataSourceAwsKmsKeyConfig, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccDataSourceAwsKmsKeyCheck("data.aws_kms_key.arbitrary"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: Can you add simple state checks for other attributes we're expecting to set? This helps with future maintainability. 👍 e.g. (not exhaustive below)
|
||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccDataSourceAwsKmsKeyCheck(name string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[name] | ||
if !ok { | ||
return fmt.Errorf("root module has no resource called %s", name) | ||
} | ||
|
||
kmsKeyRs, ok := s.RootModule().Resources["aws_kms_key.arbitrary"] | ||
if !ok { | ||
return fmt.Errorf("can't find aws_kms_key.arbitrary in state") | ||
} | ||
|
||
attr := rs.Primary.Attributes | ||
|
||
checkProperties := []string{"arn", "key_usage", "description"} | ||
|
||
for _, p := range checkProperties { | ||
if attr[p] != kmsKeyRs.Primary.Attributes[p] { | ||
return fmt.Errorf( | ||
"%s is %s; want %s", | ||
p, | ||
attr[p], | ||
kmsKeyRs.Primary.Attributes[p], | ||
) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
const testAccDataSourceAwsKmsKeyConfig = ` | ||
resource "aws_kms_key" "arbitrary" { | ||
description = "Terraform acc test" | ||
deletion_window_in_days = 7 | ||
} | ||
|
||
data "aws_kms_key" "arbitrary" { | ||
key_id = "${aws_kms_key.arbitrary.key_id}" | ||
}` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1972,3 +1972,20 @@ func validateDxConnectionBandWidth(v interface{}, k string) (ws []string, errors | |
errors = append(errors, fmt.Errorf("expected %s to be one of %v, got %s", k, validBandWidth, val)) | ||
return | ||
} | ||
|
||
func validateKmsKey(v interface{}, k string) (ws []string, errors []error) { | ||
value := v.(string) | ||
arnPrefixPattern := `arn:[\w-]+:([a-zA-Z0-9\-])+:([a-z]{2}-(gov-)?[a-z]+-\d{1})?:(\d{12})?:` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we switch this to not assume anything about the format of AWS partitions, regions, and account IDs in the future please? |
||
keyIdPattern := "[A-Za-z0-9-]+" | ||
keyArnPattern := arnPrefixPattern + "key/" + keyIdPattern | ||
aliasNamePattern := "alias/[a-zA-Z0-9:/_-]+" | ||
aliasArnPattern := arnPrefixPattern + aliasNamePattern | ||
if !regexp.MustCompile(fmt.Sprintf("^%s$", keyIdPattern)).MatchString(value) && | ||
!regexp.MustCompile(fmt.Sprintf("^%s$", keyArnPattern)).MatchString(value) && | ||
!regexp.MustCompile(fmt.Sprintf("^%s$", aliasNamePattern)).MatchString(value) && | ||
!regexp.MustCompile(fmt.Sprintf("^%s$", aliasArnPattern)).MatchString(value) { | ||
errors = append(errors, fmt.Errorf("%q must be one of the following patterns: %s, %s, %s or %s", k, keyIdPattern, keyArnPattern, aliasNamePattern, aliasArnPattern)) | ||
} | ||
|
||
return | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2774,6 +2774,53 @@ func TestValidateDxConnectionBandWidth(t *testing.T) { | |
} | ||
} | ||
|
||
func TestValidateKmsKey(t *testing.T) { | ||
cases := []struct { | ||
Value string | ||
ErrCount int | ||
}{ | ||
{ | ||
Value: "arbitrary-uuid-1234", | ||
ErrCount: 0, | ||
}, | ||
{ | ||
Value: "arn:aws:kms:us-west-2:111122223333:key/arbitrary-uuid-1234", | ||
ErrCount: 0, | ||
}, | ||
{ | ||
Value: "alias/arbitrary-key", | ||
ErrCount: 0, | ||
}, | ||
{ | ||
Value: "alias/arbitrary/key", | ||
ErrCount: 0, | ||
}, | ||
{ | ||
Value: "arn:aws:kms:us-west-2:111122223333:alias/arbitrary-key", | ||
ErrCount: 0, | ||
}, | ||
{ | ||
Value: "arn:aws:kms:us-west-2:111122223333:alias/arbitrary/key", | ||
ErrCount: 0, | ||
}, | ||
{ | ||
Value: "$%wrongkey", | ||
ErrCount: 1, | ||
}, | ||
{ | ||
Value: "arn:aws:lamda:foo:bar:key/xyz", | ||
ErrCount: 1, | ||
}, | ||
} | ||
|
||
for _, tc := range cases { | ||
_, errors := validateKmsKey(tc.Value, "key_id") | ||
if len(errors) != tc.ErrCount { | ||
t.Fatalf("%q validation failed: %v", tc.Value, errors) | ||
} | ||
} | ||
} | ||
|
||
func TestValidateCognitoUserPoolReplyEmailAddress(t *testing.T) { | ||
validTypes := []string{ | ||
"[email protected]", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
layout: "aws" | ||
page_title: "AWS: aws_kms_key" | ||
sidebar_current: "docs-aws-datasource-kms-key" | ||
description: |- | ||
Get information on a AWS Key Management Service (KMS) Key | ||
--- | ||
|
||
# aws\_kms\_key | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: Backslashes are no longer required in the documentation headers |
||
|
||
Use this data source to get detailed information about | ||
the specified KMS Key with flexible key id input. | ||
This can be useful to reference key alias | ||
without having to hard code the ARN as input. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
data "aws_kms_key" "foo" { | ||
key_id = "alias/my-key" | ||
} | ||
|
||
data "aws_kms_key" "foo" { | ||
key_id = "1234abcd-12ab-34cd-56ef-1234567890ab" | ||
} | ||
|
||
data "aws_kms_key" "foo" { | ||
key_id = "arn:aws:kms:us-east-1:111122223333:alias/my-key" | ||
} | ||
|
||
data "aws_kms_key" "foo" { | ||
key_id = "arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
* `key_id` - (Required) Key identifier which can be one of the following format: | ||
* Key ID. E.g: `1234abcd-12ab-34cd-56ef-1234567890ab` | ||
* Key ARN. E.g.: `arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab` | ||
* Alias name. E.g.: `alias/my-key` | ||
* Alias ARN: E.g.: `arn:aws:kms:us-east-1:111122223333:alias/my-key` | ||
* `grant_tokens` - (Optional) List of grant tokens | ||
|
||
## Attributes Reference | ||
|
||
* `id`: The globally unique identifier for the key | ||
* `arn`: The Amazon Resource Name (ARN) of the key | ||
* `aws_account_id`: The twelve-digit account ID of the AWS account that owns the key | ||
* `creation_date`: The date and time when the key was created | ||
* `deletion_date`: The date and time after which AWS KMS deletes the key. This value is present only when `key_state` is `PendingDeletion`, otherwise this value is 0 | ||
* `description`: The description of the key. | ||
* `enabled`: Specifies whether the key is enabled. When `key_state` is `Enabled` this value is true, otherwise it is false | ||
* `expiration_model`: Specifies whether the Key's key material expires. This value is present only when `origin` is `EXTERNAL`, otherwise this value is empty | ||
* `key_manager`: The key's manager | ||
* `key_state`: The state of the key | ||
* `key_usage`: Currently the only allowed value is `ENCRYPT_DECRYPT` | ||
* `origin`: When this value is `AWS_KMS`, AWS KMS created the key material. When this value is `EXTERNAL`, the key material was imported from your existing key management infrastructure or the CMK lacks key material | ||
* `valid_to`: The time at which the imported key material expires. This value is present only when `origin` is `EXTERNAL` and whose `expiration_model` is `KEY_MATERIAL_EXPIRES`, otherwise this value is 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Required: true
is set, so this can simply bekeyId := d.Get("key_id")