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/key_vault_(key|secret): updating the latest version when updating metadata #8304

Merged
merged 2 commits into from
Sep 1, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ func resourceArmKeyVaultKeyUpdate(d *schema.ResourceData, meta interface{}) erro
parameters.KeyAttributes.Expires = &expirationUnixTime
}

if _, err = client.UpdateKey(ctx, id.KeyVaultBaseUrl, id.Name, id.Version, parameters); err != nil {
if _, err = client.UpdateKey(ctx, id.KeyVaultBaseUrl, id.Name, "", parameters); err != nil {
return err
}

Expand Down
28 changes: 14 additions & 14 deletions azurerm/internal/services/keyvault/key_vault_secret_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,31 +241,31 @@ func resourceArmKeyVaultSecretUpdate(d *schema.ResourceData, meta interface{}) e
if _, err = client.SetSecret(ctx, id.KeyVaultBaseUrl, id.Name, parameters); err != nil {
return err
}

// "" indicates the latest version
read, err2 := client.GetSecret(ctx, id.KeyVaultBaseUrl, id.Name, "")
if err2 != nil {
return fmt.Errorf("Error getting Key Vault Secret %q : %+v", id.Name, err2)
}

if _, err = azure.ParseKeyVaultChildID(*read.ID); err != nil {
return err
}

// the ID is suffixed with the secret version
d.SetId(*read.ID)
} else {
parameters := keyvault.SecretUpdateParameters{
ContentType: utils.String(contentType),
Tags: tags.Expand(t),
SecretAttributes: secretAttributes,
}

if _, err = client.UpdateSecret(ctx, id.KeyVaultBaseUrl, id.Name, id.Version, parameters); err != nil {
if _, err = client.UpdateSecret(ctx, id.KeyVaultBaseUrl, id.Name, "", parameters); err != nil {
return err
}
}

// "" indicates the latest version
read, err2 := client.GetSecret(ctx, id.KeyVaultBaseUrl, id.Name, "")
if err2 != nil {
return fmt.Errorf("Error getting Key Vault Secret %q : %+v", id.Name, err2)
}

if _, err = azure.ParseKeyVaultChildID(*read.ID); err != nil {
return err
}

// the ID is suffixed with the secret version
d.SetId(*read.ID)

return resourceArmKeyVaultSecretRead(d, meta)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"fmt"
"log"
"testing"
"time"

"github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
"github.com/Azure/go-autorest/autorest/date"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
Expand Down Expand Up @@ -218,6 +221,37 @@ func TestAccAzureRMKeyVaultKey_update(t *testing.T) {
})
}

func TestAccAzureRMKeyVaultKey_updatedExternally(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_key_vault_key", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMKeyVaultKey_basicEC(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKeyVaultKeyExists(data.ResourceName),
updateExpiryDateForKeyVaultKey(data.ResourceName, "2029-02-02T12:59:00Z"),
),
ExpectNonEmptyPlan: true,
},
{
Config: testAccAzureRMKeyVaultKey_basicECUpdatedExternally(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKeyVaultKeyExists(data.ResourceName),
),
},
{
Config: testAccAzureRMKeyVaultKey_basicECUpdatedExternally(data),
PlanOnly: true,
},
data.ImportStep("key_size"),
},
})
}

func TestAccAzureRMKeyVaultKey_disappears(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_key_vault_key", "test")

Expand Down Expand Up @@ -340,6 +374,60 @@ func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFu
}
}

func updateExpiryDateForKeyVaultKey(resourceName string, expiryDate string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := acceptance.AzureProvider.Meta().(*clients.Client).KeyVault.ManagementClient
vaultClient := acceptance.AzureProvider.Meta().(*clients.Client).KeyVault.VaultsClient
ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext

// Ensure we have enough information in state to look up in API
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Not found: %s", resourceName)
}
name := rs.Primary.Attributes["name"]
keyVaultId := rs.Primary.Attributes["key_vault_id"]
vaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId)
if err != nil {
return fmt.Errorf("Error looking up Secret %q vault url from id %q: %+v", name, keyVaultId, err)
}

ok, err = azure.KeyVaultExists(ctx, acceptance.AzureProvider.Meta().(*clients.Client).KeyVault.VaultsClient, keyVaultId)
if err != nil {
return fmt.Errorf("Error checking if key vault %q for Key %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err)
}
if !ok {
log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl)
return nil
}

expirationDate, err := time.Parse(time.RFC3339, expiryDate)
if err != nil {
return err
}
expirationUnixTime := date.UnixTime(expirationDate)
update := keyvault.KeyUpdateParameters{
KeyAttributes: &keyvault.KeyAttributes{
Expires: &expirationUnixTime,
},
}
if _, err = client.UpdateKey(ctx, vaultBaseUrl, name, "", update); err != nil {
return fmt.Errorf("updating secret: %+v", err)
}

resp, err := client.GetKey(ctx, vaultBaseUrl, name, "")
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Bad: Key Vault Key %q (resource group: %q) does not exist", name, vaultBaseUrl)
}

return fmt.Errorf("Bad: Get on keyVaultManagementClient: %+v", err)
}

return nil
}
}

func testCheckAzureRMKeyVaultKeyDisappears(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := acceptance.AzureProvider.Meta().(*clients.Client).KeyVault.ManagementClient
Expand Down Expand Up @@ -411,6 +499,7 @@ resource "azurerm_key_vault" "test" {
"create",
"delete",
"get",
"update",
]

secret_permissions = [
Expand Down Expand Up @@ -439,6 +528,70 @@ resource "azurerm_key_vault_key" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString)
}

func testAccAzureRMKeyVaultKey_basicECUpdatedExternally(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

data "azurerm_client_config" "current" {
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_key_vault" "test" {
name = "acctestkv-%s"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
tenant_id = data.azurerm_client_config.current.tenant_id

sku_name = "premium"

access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id

key_permissions = [
"create",
"delete",
"get",
"update",
]

secret_permissions = [
"get",
"delete",
"set",
]
}

tags = {
environment = "Production"
}
}

resource "azurerm_key_vault_key" "test" {
name = "key-%s"
key_vault_id = azurerm_key_vault.test.id
key_type = "EC"
key_size = 2048
expiration_date = "2029-02-02T12:59:00Z"

key_opts = [
"sign",
"verify",
]

tags = {
Rick = "Morty"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString)
}

func testAccAzureRMKeyVaultKey_requiresImport(data acceptance.TestData) string {
template := testAccAzureRMKeyVaultKey_basicEC(data)
return fmt.Sprintf(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"testing"

"github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
Expand Down Expand Up @@ -146,6 +147,38 @@ func TestAccAzureRMKeyVaultSecret_update(t *testing.T) {
})
}

func TestAccAzureRMKeyVaultSecret_updatingValueChangedExternally(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_key_vault_secret", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMKeyVaultSecretDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMKeyVaultSecret_basic(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKeyVaultSecretExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "value", "rick-and-morty"),
updateKeyVaultSecretValue(data.ResourceName, "mad-scientist"),
),
ExpectNonEmptyPlan: true,
},
{
Config: testAccAzureRMKeyVaultSecret_updateTags(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKeyVaultSecretExists(data.ResourceName),
),
},
{
Config: testAccAzureRMKeyVaultSecret_updateTags(data),
PlanOnly: true,
},
data.ImportStep(),
},
})
}

func TestAccAzureRMKeyVaultSecret_recovery(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_key_vault_secret", "test")

Expand Down Expand Up @@ -299,6 +332,43 @@ func testCheckAzureRMKeyVaultSecretDisappears(resourceName string) resource.Test
}
}

func updateKeyVaultSecretValue(resourceName, value string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := acceptance.AzureProvider.Meta().(*clients.Client).KeyVault.ManagementClient
vaultClient := acceptance.AzureProvider.Meta().(*clients.Client).KeyVault.VaultsClient
ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext

// Ensure we have enough information in state to look up in API
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Not found: %s", resourceName)
}
name := rs.Primary.Attributes["name"]
keyVaultId := rs.Primary.Attributes["key_vault_id"]
vaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId)
if err != nil {
return fmt.Errorf("Error looking up Secret %q vault url from id %q: %+v", name, keyVaultId, err)
}

ok, err = azure.KeyVaultExists(ctx, acceptance.AzureProvider.Meta().(*clients.Client).KeyVault.VaultsClient, keyVaultId)
if err != nil {
return fmt.Errorf("Error checking if key vault %q for Secret %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err)
}
if !ok {
log.Printf("[DEBUG] Secret %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl)
return nil
}

updated := keyvault.SecretSetParameters{
Value: utils.String(value),
}
if _, err = client.SetSecret(ctx, vaultBaseUrl, name, updated); err != nil {
return fmt.Errorf("updating secret: %+v", err)
}
return nil
}
}

func testAccAzureRMKeyVaultSecret_basic(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down Expand Up @@ -349,6 +419,60 @@ resource "azurerm_key_vault_secret" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString)
}

func testAccAzureRMKeyVaultSecret_updateTags(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

data "azurerm_client_config" "current" {
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_key_vault" "test" {
name = "acctestkv-%s"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
tenant_id = data.azurerm_client_config.current.tenant_id

sku_name = "premium"

access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id

key_permissions = [
"get",
]

secret_permissions = [
"get",
"delete",
"set",
]
}

tags = {
environment = "Production"
}
}

resource "azurerm_key_vault_secret" "test" {
name = "secret-%s"
value = "mad-scientist"
key_vault_id = azurerm_key_vault.test.id

tags = {
Rick = "Morty"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString)
}

func testAccAzureRMKeyVaultSecret_requiresImport(data acceptance.TestData) string {
template := testAccAzureRMKeyVaultSecret_basic(data)
return fmt.Sprintf(`
Expand Down