diff --git a/docs/resources/certificate_signing_request_v1.md b/docs/resources/certificate_signing_request_v1.md index 723980871f..49183a4478 100644 --- a/docs/resources/certificate_signing_request_v1.md +++ b/docs/resources/certificate_signing_request_v1.md @@ -97,6 +97,18 @@ Custom signerNames can also be specified. The signer defines: Optional: +- `expiration_seconds` (Integer) expirationSeconds is the requested duration of validity of the issued certificate. + +The certificate signer may issue a certificate with a different validity duration so a client must check the delta between the notBefore and and notAfter fields in the issued certificate to determine the actual duration. The v1.22+ in-tree implementations of the well-known Kubernetes signers will honor this field as long as the requested duration is not greater than the maximum duration they will honor per the --cluster-signing-duration CLI flag to the Kubernetes controller manager. + +Certificate signers may not honor this field for various reasons: + +1. Old signer that is unaware of the field (such as the in-tree implementations prior to v1.22) +2. Signer whose configured maximum is shorter than the requested duration +3. Signer whose configured minimum is longer than the requested duration + +The minimum valid value for expirationSeconds is 600, i.e. 10 minutes. + - `usages` (Set of String) usages specifies a set of key usages requested in the issued certificate. Requests for TLS client certificates typically request: "digital signature", "key encipherment", "client auth". diff --git a/kubernetes/resource_kubernetes_certificate_signing_request_v1.go b/kubernetes/resource_kubernetes_certificate_signing_request_v1.go index 48e9f4361a..1a45d5f903 100644 --- a/kubernetes/resource_kubernetes_certificate_signing_request_v1.go +++ b/kubernetes/resource_kubernetes_certificate_signing_request_v1.go @@ -57,6 +57,12 @@ func resourceKubernetesCertificateSigningRequestV1() *schema.Resource { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "expiration_seconds": { + Type: schema.TypeInt, + Description: apiDocSpec["expirationSeconds"], + Optional: true, + ForceNew: true, + }, "request": { Type: schema.TypeString, Description: apiDocSpec["request"], diff --git a/kubernetes/resource_kubernetes_certificate_signing_request_v1_test.go b/kubernetes/resource_kubernetes_certificate_signing_request_v1_test.go index 1c23fb57fa..6c4d6c743b 100644 --- a/kubernetes/resource_kubernetes_certificate_signing_request_v1_test.go +++ b/kubernetes/resource_kubernetes_certificate_signing_request_v1_test.go @@ -39,6 +39,7 @@ func TestAccKubernetesCertificateSigningRequestV1_basic(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "certificate"), resource.TestCheckResourceAttr(resourceName, "spec.0.signer_name", signerName), resource.TestCheckResourceAttr(resourceName, "spec.0.usages.0", usages[0]), + resource.TestCheckResourceAttr(resourceName, "spec.0.expiration_seconds", "604800"), ), }, }, @@ -150,7 +151,8 @@ func testAccKubernetesCertificateSigningRequestV1Config_basic(name, signerName s } auto_approve = %t spec { - request = <= 600 { + obj.ExpirationSeconds = ptr.To(int32(v)) + } obj.Request = []byte(in["request"].(string)) if v, ok := in["usages"].(*schema.Set); ok && v.Len() > 0 { obj.Usages = expandCertificateSigningRequestV1Usages(v.List())