From 216098b9ca593716a21b2a47dbb456b40756eec8 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Mon, 8 Aug 2022 13:41:21 -0500 Subject: [PATCH 01/12] Add bootstrap to schema --- vault/resource_consul_secret_backend.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index 8f42300ca..eb20ff1c7 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -70,6 +70,12 @@ func consulSecretBackendResource() *schema.Resource { Description: "Specifies the Consul ACL token to use. This must be a management type token.", Sensitive: true, }, + "bootstrap": { + Type: schema.TypeBool, + Optional: true, + Description: "Denotes a backend resource that was used to bootstrap the Consul ACL system.", + Default: false, + }, "ca_cert": { Type: schema.TypeString, Optional: true, From a502ae0eba3afa8f692ad43db34094a9b19ac8c0 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Mon, 8 Aug 2022 14:08:26 -0500 Subject: [PATCH 02/12] Add CustomizeDiff to manage token and bootstrap fields --- vault/resource_consul_secret_backend.go | 37 +++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index eb20ff1c7..880532504 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -1,6 +1,7 @@ package vault import ( + "context" "fmt" "log" "strings" @@ -13,11 +14,12 @@ import ( func consulSecretBackendResource() *schema.Resource { return &schema.Resource{ - Create: consulSecretBackendCreate, - Read: ReadWrapper(consulSecretBackendRead), - Update: consulSecretBackendUpdate, - Delete: consulSecretBackendDelete, - Exists: consulSecretBackendExists, + Create: consulSecretBackendCreate, + Read: consulSecretBackendRead, + Update: consulSecretBackendUpdate, + Delete: consulSecretBackendDelete, + Exists: consulSecretBackendExists, + CustomizeDiff: consulSecretsBackendCustomizeDiff, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -294,3 +296,28 @@ func consulSecretBackendExists(d *schema.ResourceData, meta interface{}) (bool, func consulSecretBackendConfigPath(backend string) string { return strings.Trim(backend, "/") + "/config/access" } + +func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceDiff, _ interface{}) error { + oldToken, newToken := diff.GetChange("token") + ob, nb := diff.GetChange("bootstrap") + oldBootstrap := ob.(bool) + newBootstrap := nb.(bool) + + // If the user sets bootstrap to false but doesn't provide a token, disallow it + if newToken == "" && !newBootstrap { + return fmt.Errorf("field `bootstrap` must be set to true when `token` is unspecified for Consul bootstrapping") + } + + // If the user sets bootstrap to true but also provides a token, disallow it + if newToken != "" && newBootstrap { + return fmt.Errorf("field `bootstrap` must be set to false when `token` is specified") + } + + // If the user already has a bootstrap resource, but tries updating the resource to add a token, + // disallow it + if oldBootstrap && oldToken == "" && newToken != "" { + return fmt.Errorf("cannot change field `token` on a Consul backend resource with bootstrap") + } + + return nil +} From 9bc70c8589579f6ad17eb0a77f118562f6eb99d6 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Mon, 8 Aug 2022 14:57:08 -0500 Subject: [PATCH 03/12] Update token field description --- vault/resource_consul_secret_backend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index 880532504..885c0c29c 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -69,7 +69,7 @@ func consulSecretBackendResource() *schema.Resource { "token": { Type: schema.TypeString, Optional: true, - Description: "Specifies the Consul ACL token to use. This must be a management type token.", + Description: "Specifies the Consul token to use when managing or issuing new tokens.", Sensitive: true, }, "bootstrap": { From 8aa59090dbb9373692cb472b314548d818ba135f Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Mon, 8 Aug 2022 15:00:44 -0500 Subject: [PATCH 04/12] Add error when users attempt to change a non-bootstrap resource into a bootstrap resource --- vault/resource_consul_secret_backend.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index 885c0c29c..0247927d6 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -313,11 +313,17 @@ func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceD return fmt.Errorf("field `bootstrap` must be set to false when `token` is specified") } - // If the user already has a bootstrap resource, but tries updating the resource to add a token, - // disallow it + // If the user already has a bootstrap resource created, but tries updating the resource to add + // a token, disallow it if oldBootstrap && oldToken == "" && newToken != "" { return fmt.Errorf("cannot change field `token` on a Consul backend resource with bootstrap") } + // If the user already has a non-bootstrap resource, but tries updating the resource to remove + // the token and set bootstrap to true, disallow it + if !oldBootstrap && oldToken != "" && newBootstrap { + return fmt.Errorf("cannot change field `bootstrap` on a Consul backend resource without bootstrap") + } + return nil } From 26744de5dd6662e766febb48dc381c6931c5dd74 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Mon, 8 Aug 2022 15:20:13 -0500 Subject: [PATCH 05/12] Update wording --- vault/resource_consul_secret_backend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index 0247927d6..cc4bd6f62 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -305,7 +305,7 @@ func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceD // If the user sets bootstrap to false but doesn't provide a token, disallow it if newToken == "" && !newBootstrap { - return fmt.Errorf("field `bootstrap` must be set to true when `token` is unspecified for Consul bootstrapping") + return fmt.Errorf("field `bootstrap` must be set to true when `token` is unspecified") } // If the user sets bootstrap to true but also provides a token, disallow it From 4716fa148f93f6e5a305926682db645ca6154d27 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Mon, 8 Aug 2022 15:37:01 -0500 Subject: [PATCH 06/12] Add two more error scenarios and change order of error checking --- vault/resource_consul_secret_backend.go | 36 ++++++++++++++++--------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index cc4bd6f62..aaf1e0e4b 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -303,6 +303,30 @@ func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceD oldBootstrap := ob.(bool) newBootstrap := nb.(bool) + // If the user already has a bootstrap resource created, but tries updating the resource to add + // a token, disallow it + if oldBootstrap && oldToken == "" { + if newToken != "" { + return fmt.Errorf("cannot change field `token` on a Consul secret backend resource with bootstrap") + } + + if !newBootstrap { + return fmt.Errorf("cannot change field `bootstrap` on a Consul secret backend resource with bootstrap") + } + } + + // If the user already has a non-bootstrap resource, but tries updating the resource to remove + // the token and set bootstrap to true, disallow it + if !oldBootstrap && oldToken != "" { + if newToken == "" { + return fmt.Errorf("cannot remove field `token` on a Consul secret backend resource without bootstrap") + } + + if newBootstrap { + return fmt.Errorf("cannot change field `bootstrap` on a Consul secret backend resource without bootstrap") + } + } + // If the user sets bootstrap to false but doesn't provide a token, disallow it if newToken == "" && !newBootstrap { return fmt.Errorf("field `bootstrap` must be set to true when `token` is unspecified") @@ -313,17 +337,5 @@ func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceD return fmt.Errorf("field `bootstrap` must be set to false when `token` is specified") } - // If the user already has a bootstrap resource created, but tries updating the resource to add - // a token, disallow it - if oldBootstrap && oldToken == "" && newToken != "" { - return fmt.Errorf("cannot change field `token` on a Consul backend resource with bootstrap") - } - - // If the user already has a non-bootstrap resource, but tries updating the resource to remove - // the token and set bootstrap to true, disallow it - if !oldBootstrap && oldToken != "" && newBootstrap { - return fmt.Errorf("cannot change field `bootstrap` on a Consul backend resource without bootstrap") - } - return nil } From 043b26dea3c3d5f5d4d4e57e35bb160583c97b61 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Mon, 8 Aug 2022 15:43:30 -0500 Subject: [PATCH 07/12] Update code comments for clarity --- vault/resource_consul_secret_backend.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index aaf1e0e4b..156df1de2 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -303,36 +303,38 @@ func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceD oldBootstrap := ob.(bool) newBootstrap := nb.(bool) - // If the user already has a bootstrap resource created, but tries updating the resource to add - // a token, disallow it + // Disallow the following bad states on existing resource updates if oldBootstrap && oldToken == "" { + // If the user already has a bootstrap resource created, but tries adding a token if newToken != "" { return fmt.Errorf("cannot change field `token` on a Consul secret backend resource with bootstrap") } + // If the user already has a bootstrap resource created, but tries setting bootstrap to false if !newBootstrap { return fmt.Errorf("cannot change field `bootstrap` on a Consul secret backend resource with bootstrap") } } - // If the user already has a non-bootstrap resource, but tries updating the resource to remove - // the token and set bootstrap to true, disallow it if !oldBootstrap && oldToken != "" { + // If the user already has a non-bootstrap resource, but tries removing the token if newToken == "" { return fmt.Errorf("cannot remove field `token` on a Consul secret backend resource without bootstrap") } + // If the user already has a non-bootstrap resource, but tries setting bootstrap to true if newBootstrap { return fmt.Errorf("cannot change field `bootstrap` on a Consul secret backend resource without bootstrap") } } - // If the user sets bootstrap to false but doesn't provide a token, disallow it + // Disallow the following bad states on new resources + // If the user sets bootstrap to false but doesn't provide a token if newToken == "" && !newBootstrap { return fmt.Errorf("field `bootstrap` must be set to true when `token` is unspecified") } - // If the user sets bootstrap to true but also provides a token, disallow it + // If the user sets bootstrap to true and also provides a token if newToken != "" && newBootstrap { return fmt.Errorf("field `bootstrap` must be set to false when `token` is specified") } From 255a384d9572f2f58dcaf77d0c0db94bd3a6fec4 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Wed, 10 Aug 2022 22:19:42 -0500 Subject: [PATCH 08/12] Simplify token and bootstrap rules, add back ReadWrapper --- vault/resource_consul_secret_backend.go | 42 +++++-------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index 156df1de2..6f0c30b63 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -15,7 +15,7 @@ import ( func consulSecretBackendResource() *schema.Resource { return &schema.Resource{ Create: consulSecretBackendCreate, - Read: consulSecretBackendRead, + Read: ReadWrapper(consulSecretBackendRead), Update: consulSecretBackendUpdate, Delete: consulSecretBackendDelete, Exists: consulSecretBackendExists, @@ -75,7 +75,7 @@ func consulSecretBackendResource() *schema.Resource { "bootstrap": { Type: schema.TypeBool, Optional: true, - Description: "Denotes a backend resource that was used to bootstrap the Consul ACL system.", + Description: "Denotes a backend resource that is used to bootstrap the Consul ACL system.", Default: false, }, "ca_cert": { @@ -165,7 +165,7 @@ func consulSecretBackendCreate(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] Wrote Consul configuration to %q", configPath) d.Partial(false) - return nil + return consulSecretBackendRead(d, meta) } func consulSecretBackendRead(d *schema.ResourceData, meta interface{}) error { @@ -298,43 +298,15 @@ func consulSecretBackendConfigPath(backend string) string { } func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceDiff, _ interface{}) error { - oldToken, newToken := diff.GetChange("token") - ob, nb := diff.GetChange("bootstrap") - oldBootstrap := ob.(bool) - newBootstrap := nb.(bool) - - // Disallow the following bad states on existing resource updates - if oldBootstrap && oldToken == "" { - // If the user already has a bootstrap resource created, but tries adding a token - if newToken != "" { - return fmt.Errorf("cannot change field `token` on a Consul secret backend resource with bootstrap") - } - - // If the user already has a bootstrap resource created, but tries setting bootstrap to false - if !newBootstrap { - return fmt.Errorf("cannot change field `bootstrap` on a Consul secret backend resource with bootstrap") - } - } - - if !oldBootstrap && oldToken != "" { - // If the user already has a non-bootstrap resource, but tries removing the token - if newToken == "" { - return fmt.Errorf("cannot remove field `token` on a Consul secret backend resource without bootstrap") - } - - // If the user already has a non-bootstrap resource, but tries setting bootstrap to true - if newBootstrap { - return fmt.Errorf("cannot change field `bootstrap` on a Consul secret backend resource without bootstrap") - } - } + newToken := diff.Get("token").(string) + newBootstrap := diff.Get("bootstrap").(bool) - // Disallow the following bad states on new resources - // If the user sets bootstrap to false but doesn't provide a token + // If the user sets bootstrap to false but doesn't provide a token, disallow it. if newToken == "" && !newBootstrap { return fmt.Errorf("field `bootstrap` must be set to true when `token` is unspecified") } - // If the user sets bootstrap to true and also provides a token + // If the user sets bootstrap to true and also provides a token, disallow it. if newToken != "" && newBootstrap { return fmt.Errorf("field `bootstrap` must be set to false when `token` is specified") } From 36266461c26699dfd35191a67febe4b0ca96cd00 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Wed, 10 Aug 2022 22:20:37 -0500 Subject: [PATCH 09/12] Update test cases for bootstrap rules --- vault/resource_consul_secret_backend_test.go | 40 ++++++++++++++------ 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/vault/resource_consul_secret_backend_test.go b/vault/resource_consul_secret_backend_test.go index 0856c56d7..e12ad2839 100644 --- a/vault/resource_consul_secret_backend_test.go +++ b/vault/resource_consul_secret_backend_test.go @@ -42,7 +42,8 @@ func TestConsulSecretBackend(t *testing.T) { resource.TestCheckNoResourceAttr(resourceName, "client_key"), ), }, - testutil.GetImportTestStep(resourceName, false, "token", "ca_cert", "client_cert", "client_key"), + testutil.GetImportTestStep(resourceName, false, + "token", "bootstrap", "ca_cert", "client_cert", "client_key"), { Config: testConsulSecretBackend_initialConfigLocal(path, token), Check: resource.ComposeTestCheckFunc( @@ -59,7 +60,8 @@ func TestConsulSecretBackend(t *testing.T) { resource.TestCheckNoResourceAttr(resourceName, "client_key"), ), }, - testutil.GetImportTestStep(resourceName, false, "token", "ca_cert", "client_cert", "client_key"), + testutil.GetImportTestStep(resourceName, false, + "token", "bootstrap", "ca_cert", "client_cert", "client_key"), { Config: testConsulSecretBackend_updateConfig(path, token), Check: resource.ComposeTestCheckFunc( @@ -76,7 +78,8 @@ func TestConsulSecretBackend(t *testing.T) { resource.TestCheckNoResourceAttr(resourceName, "client_key"), ), }, - testutil.GetImportTestStep(resourceName, false, "token", "ca_cert", "client_cert", "client_key"), + testutil.GetImportTestStep(resourceName, false, + "token", "bootstrap", "ca_cert", "client_cert", "client_key"), { Config: testConsulSecretBackend_updateConfig_addCerts(path, token), Check: resource.ComposeTestCheckFunc( @@ -93,7 +96,8 @@ func TestConsulSecretBackend(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "client_key", "FAKE-CLIENT-CERT-KEY-MATERIAL"), ), }, - testutil.GetImportTestStep(resourceName, false, "token", "ca_cert", "client_cert", "client_key"), + testutil.GetImportTestStep(resourceName, false, + "token", "bootstrap", "ca_cert", "client_cert", "client_key"), { Config: testConsulSecretBackend_updateConfig_updateCerts(path, token), Check: resource.ComposeTestCheckFunc( @@ -110,7 +114,8 @@ func TestConsulSecretBackend(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "client_key", "UPDATED-FAKE-CLIENT-CERT-KEY-MATERIAL"), ), }, - testutil.GetImportTestStep(resourceName, false, "token", "ca_cert", "client_cert", "client_key"), + testutil.GetImportTestStep(resourceName, false, + "token", "bootstrap", "ca_cert", "client_cert", "client_key"), }, }) } @@ -134,13 +139,22 @@ func TestConsulSecretBackend_Bootstrap(t *testing.T) { CheckDestroy: testAccConsulSecretBackendCheckDestroy, Steps: []resource.TestStep{ { - Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr), + Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "", "false"), + ExpectError: regexp.MustCompile("field `bootstrap` must be set to true when `token` is unspecified"), + }, + { + Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "token", "true"), + ExpectError: regexp.MustCompile("field `bootstrap` must be set to false when `token` is specified"), + }, + { + Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "", "true"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, consts.FieldPath, path), resource.TestCheckResourceAttr(resourceName, "address", consulAddr), + resource.TestCheckResourceAttr(resourceName, "bootstrap", "true"), ), }, - testutil.GetImportTestStep(resourceName, false), + testutil.GetImportTestStep(resourceName, false, "token", "bootstrap"), { Config: testConsulSecretBackend_bootstrapAddRole(path, consulAddr), Check: resource.ComposeTestCheckFunc( @@ -150,9 +164,9 @@ func TestConsulSecretBackend_Bootstrap(t *testing.T) { resource.TestCheckTypeSetElemAttr(resourceRoleName, "consul_policies.*", "global-management"), ), }, - testutil.GetImportTestStep(resourceName, false), + testutil.GetImportTestStep(resourceName, false, "token", "bootstrap"), { - Config: testConsulSecretBackend_bootstrapConfig(path+"-new", consulAddr), + Config: testConsulSecretBackend_bootstrapConfig(path+"-new", consulAddr, "", "true"), ExpectError: regexp.MustCompile(`Token not provided and failed to bootstrap ACLs`), }, }, @@ -211,13 +225,16 @@ resource "vault_consul_secret_backend" "test" { }`, path, token) } -func testConsulSecretBackend_bootstrapConfig(path, addr string) string { +func testConsulSecretBackend_bootstrapConfig(path, addr, token, bootstrap string) string { return fmt.Sprintf(` resource "vault_consul_secret_backend" "test" { path = "%s" description = "test description" address = "%s" -}`, path, addr) + token = "%s" + bootstrap = "%s" +} +`, path, addr, token, bootstrap) } func testConsulSecretBackend_updateConfig(path, token string) string { @@ -237,6 +254,7 @@ resource "vault_consul_secret_backend" "test" { path = "%s" description = "test description" address = "%s" + bootstrap = "true" } resource "vault_consul_secret_backend_role" "test" { From e36848249bf43080c736dc11b7be433cc45c499f Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Wed, 10 Aug 2022 23:52:26 -0500 Subject: [PATCH 10/12] Update the website documentation --- website/docs/r/consul_secret_backend.html.md | 39 ++++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/website/docs/r/consul_secret_backend.html.md b/website/docs/r/consul_secret_backend.html.md index fbfb7adb1..735949f15 100644 --- a/website/docs/r/consul_secret_backend.html.md +++ b/website/docs/r/consul_secret_backend.html.md @@ -8,7 +8,8 @@ description: |- # vault\_consul\_secret\_backend -Creates a Consul Secret Backend for Vault. Consul secret backends can then issue Consul tokens, once a role has been added to the backend. +Creates a Consul Secret Backend for Vault. Consul secret backends can then issue Consul tokens, once a role has been +added to the backend. ~> **Important** All data provided in the resource configuration will be written in cleartext to state and plan files generated by Terraform, and @@ -19,6 +20,7 @@ for more details. ## Example Usage +#### Creating a standard backend resource: ```hcl resource "vault_consul_secret_backend" "test" { path = "consul" @@ -29,6 +31,17 @@ resource "vault_consul_secret_backend" "test" { } ``` +#### Creating a backend resource to bootstrap a new Consul instance: +```hcl +resource "vault_consul_secret_backend" "test" { + path = "consul" + description = "Bootstrap the Consul backend" + + address = "127.0.0.1:8500" + bootstrap = "true" +} +``` + ## Argument Reference The following arguments are supported: @@ -38,13 +51,21 @@ The following arguments are supported: The `namespace` is always relative to the provider's configured [namespace](/docs/providers/vault#namespace). *Available only for Vault Enterprise*. -* `token` - (Required) The Consul management token this backend should use to issue new tokens. +* `token` - (Optional) The Consul management token this backend should use to issue new tokens. This field is required +when not bootstrapping a new Consul instance. + +~> **Important** Because Vault does not support reading the configured token back from the API, Terraform cannot detect +and correct drift on `token`. Changing the value, however, _will_ overwrite the previously stored values. + +* `bootstrap` - (Optional) Denotes that the resource is used to bootstrap the Consul ACL system. -~> **Important** Because Vault does not support reading the configured -token back from the API, Terraform cannot detect and correct drift -on `token`. Changing the value, however, _will_ overwrite the previously stored values. +~> **Important** The bootstrap token is silently stored. If a management token is needed, write a role with the +`global-management` policy and read new creds back from it. If the resource is destroyed or the token overwritten, the +bootstrap token will be lost and [an ACL system reset would be needed to recover.](https://learn.hashicorp.com/tutorials/consul/access-control-troubleshoot#reset-the-acl-system) +Using resources in this manner should be considered an advanced feature and not recommended. -* `path` - (Optional) The unique location this backend should be mounted at. Must not begin or end with a `/`. Defaults to `consul`. +* `path` - (Optional) The unique location this backend should be mounted at. Must not begin or end with a `/`. Defaults +to `consul`. * `description` - (Optional) A human-friendly description for this backend. @@ -54,9 +75,11 @@ on `token`. Changing the value, however, _will_ overwrite the previously stored * `ca_cert` - (Optional) CA certificate to use when verifying Consul server certificate, must be x509 PEM encoded. -* `client_cert` - (Optional) Client certificate used for Consul's TLS communication, must be x509 PEM encoded and if this is set you need to also set client_key. +* `client_cert` - (Optional) Client certificate used for Consul's TLS communication, must be x509 PEM encoded and if +this is set you need to also set client_key. -* `client_key` - (Optional) Client key used for Consul's TLS communication, must be x509 PEM encoded and if this is set you need to also set client_cert. +* `client_key` - (Optional) Client key used for Consul's TLS communication, must be x509 PEM encoded and if this is set +you need to also set client_cert. * `default_lease_ttl_seconds` - (Optional) The default TTL for credentials issued by this backend. From 643b59e3dc9809b860e9700c3dc44af816b07c7e Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Thu, 11 Aug 2022 13:27:25 -0500 Subject: [PATCH 11/12] Reword docs, statements, minor tweaks --- vault/resource_consul_secret_backend.go | 6 +++--- vault/resource_consul_secret_backend_test.go | 18 +++++++++--------- website/docs/r/consul_secret_backend.html.md | 19 ++++++++----------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/vault/resource_consul_secret_backend.go b/vault/resource_consul_secret_backend.go index 6f0c30b63..d9af3f32a 100644 --- a/vault/resource_consul_secret_backend.go +++ b/vault/resource_consul_secret_backend.go @@ -75,7 +75,7 @@ func consulSecretBackendResource() *schema.Resource { "bootstrap": { Type: schema.TypeBool, Optional: true, - Description: "Denotes a backend resource that is used to bootstrap the Consul ACL system.", + Description: "Denotes a backend resource that is used to bootstrap the Consul ACL system. Only one resource may be used to bootstrap.", Default: false, }, "ca_cert": { @@ -303,12 +303,12 @@ func consulSecretsBackendCustomizeDiff(_ context.Context, diff *schema.ResourceD // If the user sets bootstrap to false but doesn't provide a token, disallow it. if newToken == "" && !newBootstrap { - return fmt.Errorf("field `bootstrap` must be set to true when `token` is unspecified") + return fmt.Errorf("field 'bootstrap' must be set to true when 'token' is unspecified") } // If the user sets bootstrap to true and also provides a token, disallow it. if newToken != "" && newBootstrap { - return fmt.Errorf("field `bootstrap` must be set to false when `token` is specified") + return fmt.Errorf("field 'bootstrap' must be set to false when 'token' is specified") } return nil diff --git a/vault/resource_consul_secret_backend_test.go b/vault/resource_consul_secret_backend_test.go index e12ad2839..cedf9c0d4 100644 --- a/vault/resource_consul_secret_backend_test.go +++ b/vault/resource_consul_secret_backend_test.go @@ -139,15 +139,15 @@ func TestConsulSecretBackend_Bootstrap(t *testing.T) { CheckDestroy: testAccConsulSecretBackendCheckDestroy, Steps: []resource.TestStep{ { - Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "", "false"), - ExpectError: regexp.MustCompile("field `bootstrap` must be set to true when `token` is unspecified"), + Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "", false), + ExpectError: regexp.MustCompile("field 'bootstrap' must be set to true when 'token' is unspecified"), }, { - Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "token", "true"), - ExpectError: regexp.MustCompile("field `bootstrap` must be set to false when `token` is specified"), + Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "token", true), + ExpectError: regexp.MustCompile("field 'bootstrap' must be set to false when 'token' is specified"), }, { - Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "", "true"), + Config: testConsulSecretBackend_bootstrapConfig(path, consulAddr, "", true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, consts.FieldPath, path), resource.TestCheckResourceAttr(resourceName, "address", consulAddr), @@ -166,7 +166,7 @@ func TestConsulSecretBackend_Bootstrap(t *testing.T) { }, testutil.GetImportTestStep(resourceName, false, "token", "bootstrap"), { - Config: testConsulSecretBackend_bootstrapConfig(path+"-new", consulAddr, "", "true"), + Config: testConsulSecretBackend_bootstrapConfig(path+"-new", consulAddr, "", true), ExpectError: regexp.MustCompile(`Token not provided and failed to bootstrap ACLs`), }, }, @@ -225,14 +225,14 @@ resource "vault_consul_secret_backend" "test" { }`, path, token) } -func testConsulSecretBackend_bootstrapConfig(path, addr, token, bootstrap string) string { +func testConsulSecretBackend_bootstrapConfig(path, addr, token string, bootstrap bool) string { return fmt.Sprintf(` resource "vault_consul_secret_backend" "test" { path = "%s" description = "test description" address = "%s" token = "%s" - bootstrap = "%s" + bootstrap = %t } `, path, addr, token, bootstrap) } @@ -254,7 +254,7 @@ resource "vault_consul_secret_backend" "test" { path = "%s" description = "test description" address = "%s" - bootstrap = "true" + bootstrap = true } resource "vault_consul_secret_backend_role" "test" { diff --git a/website/docs/r/consul_secret_backend.html.md b/website/docs/r/consul_secret_backend.html.md index 735949f15..933f52087 100644 --- a/website/docs/r/consul_secret_backend.html.md +++ b/website/docs/r/consul_secret_backend.html.md @@ -25,9 +25,8 @@ for more details. resource "vault_consul_secret_backend" "test" { path = "consul" description = "Manages the Consul backend" - - address = "127.0.0.1:8500" - token = "4240861b-ce3d-8530-115a-521ff070dd29" + address = "127.0.0.1:8500" + token = "4240861b-ce3d-8530-115a-521ff070dd29" } ``` @@ -36,9 +35,8 @@ resource "vault_consul_secret_backend" "test" { resource "vault_consul_secret_backend" "test" { path = "consul" description = "Bootstrap the Consul backend" - - address = "127.0.0.1:8500" - bootstrap = "true" + address = "127.0.0.1:8500" + bootstrap = true } ``` @@ -52,17 +50,16 @@ The following arguments are supported: *Available only for Vault Enterprise*. * `token` - (Optional) The Consul management token this backend should use to issue new tokens. This field is required -when not bootstrapping a new Consul instance. +when `bootstrap` is false. ~> **Important** Because Vault does not support reading the configured token back from the API, Terraform cannot detect and correct drift on `token`. Changing the value, however, _will_ overwrite the previously stored values. * `bootstrap` - (Optional) Denotes that the resource is used to bootstrap the Consul ACL system. -~> **Important** The bootstrap token is silently stored. If a management token is needed, write a role with the -`global-management` policy and read new creds back from it. If the resource is destroyed or the token overwritten, the -bootstrap token will be lost and [an ACL system reset would be needed to recover.](https://learn.hashicorp.com/tutorials/consul/access-control-troubleshoot#reset-the-acl-system) -Using resources in this manner should be considered an advanced feature and not recommended. +~> **Important** When `bootstrap` is true, the token is silently stored. If the resource is destroyed or the token +overwritten, the bootstrap token will be lost and an [ACL system reset would be needed to recover.](https://learn.hashicorp.com/tutorials/consul/access-control-troubleshoot#reset-the-acl-system) +Using resources in this manner should be considered an advanced feature and is not recommended. * `path` - (Optional) The unique location this backend should be mounted at. Must not begin or end with a `/`. Defaults to `consul`. From 1d8aa1c2d9947019cb0b4e7b7f70093602c716d5 Mon Sep 17 00:00:00 2001 From: robmonte <17119716+robmonte@users.noreply.github.com> Date: Thu, 11 Aug 2022 14:57:11 -0500 Subject: [PATCH 12/12] Update warning message text --- website/docs/r/consul_secret_backend.html.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/r/consul_secret_backend.html.md b/website/docs/r/consul_secret_backend.html.md index 933f52087..f38d38a9b 100644 --- a/website/docs/r/consul_secret_backend.html.md +++ b/website/docs/r/consul_secret_backend.html.md @@ -57,9 +57,9 @@ and correct drift on `token`. Changing the value, however, _will_ overwrite the * `bootstrap` - (Optional) Denotes that the resource is used to bootstrap the Consul ACL system. -~> **Important** When `bootstrap` is true, the token is silently stored. If the resource is destroyed or the token -overwritten, the bootstrap token will be lost and an [ACL system reset would be needed to recover.](https://learn.hashicorp.com/tutorials/consul/access-control-troubleshoot#reset-the-acl-system) -Using resources in this manner should be considered an advanced feature and is not recommended. +~> **Important** When `bootstrap` is true, Vault will attempt to bootstrap the Consul server. The token returned from +this operation will only ever be known to Vault. If the resource is ever destroyed, the bootstrap token will be lost +and a [Consul reset may be required.](https://learn.hashicorp.com/tutorials/consul/access-control-troubleshoot#reset-the-acl-system) * `path` - (Optional) The unique location this backend should be mounted at. Must not begin or end with a `/`. Defaults to `consul`.