Skip to content

Commit

Permalink
azurerm_nginx_certificate: support update key_virtual_path, `cert…
Browse files Browse the repository at this point in the history
…ificate_virtual_path` and `key_vault_secret_id` fields (hashicorp#22100)
  • Loading branch information
wuxu92 authored Jun 12, 2023
1 parent 895f501 commit 792e998
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 8 deletions.
53 changes: 49 additions & 4 deletions internal/services/nginx/nginx_certificate_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type CertificateModel struct {

type CertificateResource struct{}

var _ sdk.Resource = (*CertificateResource)(nil)
var _ sdk.ResourceWithUpdate = (*CertificateResource)(nil)

func (m CertificateResource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
Expand All @@ -46,21 +46,18 @@ func (m CertificateResource) Arguments() map[string]*pluginsdk.Schema {
"key_virtual_path": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"certificate_virtual_path": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"key_vault_secret_id": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: keyvaultValidate.NestedItemIdWithOptionalVersion,
},
}
Expand Down Expand Up @@ -120,6 +117,54 @@ func (m CertificateResource) Create() sdk.ResourceFunc {
}
}

func (m CertificateResource) Update() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 30 * time.Minute,
Func: func(ctx context.Context, meta sdk.ResourceMetaData) error {

client := meta.Client.Nginx.NginxCertificate
id, err := nginxcertificate.ParseCertificateID(meta.ResourceData.Id())
if err != nil {
return err
}

var model CertificateModel
if err = meta.Decode(&model); err != nil {
return fmt.Errorf("decoding err: %+v", err)
}

// retrieve from GET
existing, err := client.CertificatesGet(ctx, *id)
if err != nil {
return fmt.Errorf("retrieving exists when updating: +%v", *id)
}
if existing.Model == nil && existing.Model.Properties == nil {
return fmt.Errorf("retrieving as nil when updating for %v", *id)
}

// have to pass all existing properties to update
upd := existing.Model
if meta.ResourceData.HasChange("key_virtual_path") {
upd.Properties.KeyVirtualPath = pointer.FromString(model.KeyVirtualPath)
}

if meta.ResourceData.HasChange("certificate_virtual_path") {
upd.Properties.CertificateVirtualPath = pointer.To(model.CertificateVirtualPath)
}

if meta.ResourceData.HasChange("key_vault_secret_id") {
upd.Properties.KeyVaultSecretId = pointer.To(model.KeyVaultSecretId)
}

err = client.CertificatesCreateOrUpdateThenPoll(ctx, *id, *upd)
if err != nil {
return fmt.Errorf("updating %s: %v", id, err)
}
return nil
},
}
}

func (m CertificateResource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Expand Down
83 changes: 82 additions & 1 deletion internal/services/nginx/nginx_certificate_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,27 @@ func TestAccCertificate_basic(t *testing.T) {
})
}

func TestAccCertificate_update(t *testing.T) {
data := acceptance.BuildTestData(t, nginx.CertificateResource{}.ResourceType(), "test")
r := CertificateResource{}
data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.update(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccCertificate_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, nginx.CertificateResource{}.ResourceType(), "test")
r := CertificateResource{}
Expand All @@ -59,7 +80,6 @@ func TestAccCertificate_requiresImport(t *testing.T) {
func (a CertificateResource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_nginx_certificate" "test" {
Expand All @@ -72,6 +92,67 @@ resource "azurerm_nginx_certificate" "test" {
`, a.template(data), data.RandomInteger, data.Locations.Primary)
}

func (a CertificateResource) update(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_key_vault_certificate" "test2" {
name = "acctestcert2%[2]d"
key_vault_id = azurerm_key_vault.test.id
certificate_policy {
issuer_parameters {
name = "Self"
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}
lifetime_action {
action {
action_type = "AutoRenew"
}
trigger {
days_before_expiry = 30
}
}
secret_properties {
content_type = "application/x-pem-file"
}
x509_certificate_properties {
key_usage = [
"cRLSign",
"dataEncipherment",
"digitalSignature",
"keyAgreement",
"keyEncipherment",
"keyCertSign",
]
subject = "CN=hello-world"
validity_in_months = 12
}
}
}
resource "azurerm_nginx_certificate" "test" {
name = "acctest%[2]d"
nginx_deployment_id = azurerm_nginx_deployment.test.id
key_virtual_path = "/src/cert/soservermekey2.key"
certificate_virtual_path = "/src/cert/server2.cert"
key_vault_secret_id = azurerm_key_vault_certificate.test2.secret_id
}
`, a.template(data), data.RandomInteger)
}

func (a CertificateResource) requiresImport(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
Expand Down
7 changes: 4 additions & 3 deletions website/docs/r/nginx_certificate.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ The following arguments are supported:

* `nginx_deployment_id` - (Required) The ID of the Nginx Deployment that this Certificate should be associated with. Changing this forces a new Nginx Certificate to be created.

* `certificate_virtual_path` - (Required) Specify the path to the cert file of this certificate. Changing this forces a new Nginx Certificate to be created.
* `certificate_virtual_path` - (Required) Specify the path to the cert file of this certificate.

* `key_virtual_path` - (Required) Specify the path to the key file of this certificate. Changing this forces a new Nginx Certificate to be created.
* `key_virtual_path` - (Required) Specify the path to the key file of this certificate.

* `key_vault_secret_id` - (Required) Specify the ID of the Key Vault Secret for this certificate. Changing this forces a new Nginx Certificate to be created.
* `key_vault_secret_id` - (Required) Specify the ID of the Key Vault Secret for this certificate.

## Attributes Reference

Expand All @@ -144,6 +144,7 @@ In addition to the Arguments listed above - the following Attributes are exporte
The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions:

* `create` - (Defaults to 30 minutes) Used when creating the Nginx Certificate.
* `update` - (Defaults to 30 minutes) Used when updating the Nginx Certificate.
* `read` - (Defaults to 5 minutes) Used when retrieving the Nginx Certificate.
* `delete` - (Defaults to 10 minutes) Used when deleting the Nginx Certificate.

Expand Down

0 comments on commit 792e998

Please sign in to comment.