Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into stevendpclark/vault-3…
Browse files Browse the repository at this point in the history
…2587-add-support-for-acme-eab-tokens
  • Loading branch information
stevendpclark committed Nov 29, 2024
2 parents 9ceaba4 + 435ce67 commit e63168d
Show file tree
Hide file tree
Showing 17 changed files with 591 additions and 31 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

FEATURES:

* Update `vault_database_secret_backend_connection`to support `password_authentication` for PostgreSQL, allowing to encrypt password before being passed to PostgreSQL ([#2371](https://github.com/hashicorp/terraform-provider-vault/pull/2371))
* Add support for `external_id` field for the `vault_aws_auth_backend_sts_role` resource ([#2370](https://github.com/hashicorp/terraform-provider-vault/pull/2370))
* Add support for ACME configuration with the `vault_pki_secret_backend_config_acme` resource. Requires Vault 1.14+ ([#2157](https://github.com/hashicorp/terraform-provider-vault/pull/2157)).
* Update `vault_pki_secret_backend_role` to support the `cn_validations` role field ([#1820](https://github.com/hashicorp/terraform-provider-vault/pull/1820)).
* Add new resource `vault_pki_secret_backend_acme_eab` to manage PKI ACME external account binding tokens. Requires Vault 1.14+. ([#2367](https://github.com/hashicorp/terraform-provider-vault/pull/2367))

## 4.5.0 (Nov 19, 2024)
Expand Down
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @hashicorp/vault-ecosystem
* @hashicorp/vault
8 changes: 7 additions & 1 deletion internal/consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,17 @@ const (
FieldMaxRetries = "max_retries"
FieldSessionTags = "session_tags"
FieldSelfManagedPassword = "self_managed_password"
FieldAllowedIssuers = "allowed_issuers"
FieldAllowedRoles = "allowed_roles"
FieldAllowRoleExtKeyUsage = "allow_role_ext_key_usage"
FieldDefaultDirectoryPolicy = "default_directory_policy"
FieldDnsResolver = "dns_resolver"
FieldEabPolicy = "eab_policy"
FieldCnValidations = "cn_validations"
FieldsCreatedOn = "created_on"
FieldEabKey = "key"
FieldAcmeDirectory = "acme_directory"
FieldEabId = "eab_id"

/*
common environment variables
*/
Expand Down
4 changes: 4 additions & 0 deletions vault/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,10 @@ var (
Resource: UpdateSchemaResource(pkiSecretBackendCrlConfigResource()),
PathInventory: []string{"/pki/config/crl"},
},
"vault_pki_secret_backend_config_acme": {
Resource: UpdateSchemaResource(pkiSecretBackendConfigACMEResource()),
PathInventory: []string{"/pki/config/acme"},
},
"vault_pki_secret_backend_config_ca": {
Resource: UpdateSchemaResource(pkiSecretBackendConfigCAResource()),
PathInventory: []string{"/pki/config/ca"},
Expand Down
42 changes: 36 additions & 6 deletions vault/resource_aws_auth_backend_sts_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)

Expand Down Expand Up @@ -52,6 +53,11 @@ func awsAuthBackendSTSRoleResource() *schema.Resource {
return strings.Trim(v.(string), "/")
},
},
consts.FieldExternalID: {
Type: schema.TypeString,
Optional: true,
Description: "External ID expected by the STS role.",
},
},
}
}
Expand All @@ -65,13 +71,20 @@ func awsAuthBackendSTSRoleCreate(d *schema.ResourceData, meta interface{}) error
backend := d.Get("backend").(string)
accountID := d.Get("account_id").(string)
stsRole := d.Get("sts_role").(string)
externalID := d.Get(consts.FieldExternalID).(string)

path := awsAuthBackendSTSRolePath(backend, accountID)

log.Printf("[DEBUG] Writing STS role %q to AWS auth backend", path)
_, err := client.Logical().Write(path, map[string]interface{}{
data := map[string]interface{}{
"sts_role": stsRole,
})
}

if provider.IsAPISupported(meta, provider.VaultVersion117) {
data[consts.FieldExternalID] = externalID
}

log.Printf("[DEBUG] Writing STS role %q to AWS auth backend", path)
_, err := client.Logical().Write(path, data)

d.SetId(path)

Expand Down Expand Up @@ -117,6 +130,15 @@ func awsAuthBackendSTSRoleRead(d *schema.ResourceData, meta interface{}) error {
d.Set("backend", backend)
d.Set("account_id", accountID)
d.Set("sts_role", resp.Data["sts_role"])

if provider.IsAPISupported(meta, provider.VaultVersion117) {
if v, ok := resp.Data[consts.FieldExternalID]; ok {
if err := d.Set(consts.FieldExternalID, v); err != nil {
return err
}
}
}

return nil
}

Expand All @@ -127,12 +149,20 @@ func awsAuthBackendSTSRoleUpdate(d *schema.ResourceData, meta interface{}) error
}

stsRole := d.Get("sts_role").(string)
externalID := d.Get(consts.FieldExternalID).(string)

path := d.Id()

log.Printf("[DEBUG] Updating STS role %q in AWS auth backend", path)
_, err := client.Logical().Write(path, map[string]interface{}{
data := map[string]interface{}{
"sts_role": stsRole,
})
}

if provider.IsAPISupported(meta, provider.VaultVersion117) {
data[consts.FieldExternalID] = externalID
}

log.Printf("[DEBUG] Updating STS role %q in AWS auth backend", path)
_, err := client.Logical().Write(path, data)
if err != nil {
return fmt.Errorf("error updating STS role %q in AWS auth backend", path)
}
Expand Down
73 changes: 57 additions & 16 deletions vault/resource_aws_auth_backend_sts_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,55 @@ package vault
import (
"fmt"
"strconv"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/testutil"
)

func TestAccAWSAuthBackendSTSRole_import(t *testing.T) {
func TestAccAWSAuthBackendSTSRole_withExternalID(t *testing.T) {
backend := acctest.RandomWithPrefix("aws")
accountID := strconv.Itoa(acctest.RandInt())
arn := acctest.RandomWithPrefix("arn:aws:iam::" + accountID + ":role/test-role")
externalID := "external-id"
updatedExternalID := "external-id-updated"
resourceName := "vault_aws_auth_backend_sts_role.role"

resource.Test(t, resource.TestCase{
PreCheck: func() { testutil.TestAccPreCheck(t) },
PreCheck: func() {
testutil.TestAccPreCheck(t)
SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion117)
},
ProviderFactories: providerFactories,
CheckDestroy: testAccCheckAWSAuthBackendSTSRoleDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAuthBackendSTSRoleConfig_basic(backend, accountID, arn),
Check: testAccAWSAuthBackendSTSRoleCheck_attrs(backend, accountID, arn),
Config: testAccAWSAuthBackendSTSRoleConfig(backend, accountID, arn, externalID),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "backend", backend),
resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
resource.TestCheckResourceAttr(resourceName, "sts_role", arn),
resource.TestCheckResourceAttr(resourceName, consts.FieldExternalID, externalID),
),
},
{
ResourceName: "vault_aws_auth_backend_sts_role.role",
// Update external ID.
Config: testAccAWSAuthBackendSTSRoleConfig(backend, accountID, arn, updatedExternalID),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "backend", backend),
resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
resource.TestCheckResourceAttr(resourceName, "sts_role", arn),
resource.TestCheckResourceAttr(resourceName, consts.FieldExternalID, updatedExternalID),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
Expand All @@ -49,13 +73,19 @@ func TestAccAWSAuthBackendSTSRole_basic(t *testing.T) {
CheckDestroy: testAccCheckAWSAuthBackendSTSRoleDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAuthBackendSTSRoleConfig_basic(backend, accountID, arn),
Config: testAccAWSAuthBackendSTSRoleConfig(backend, accountID, arn, ""),
Check: testAccAWSAuthBackendSTSRoleCheck_attrs(backend, accountID, arn),
},
{
Config: testAccAWSAuthBackendSTSRoleConfig_basic(backend, accountID, updatedArn),
// Update ARN.
Config: testAccAWSAuthBackendSTSRoleConfig(backend, accountID, updatedArn, ""),
Check: testAccAWSAuthBackendSTSRoleCheck_attrs(backend, accountID, updatedArn),
},
{
ResourceName: "vault_aws_auth_backend_sts_role.role",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
Expand Down Expand Up @@ -129,17 +159,28 @@ func testAccAWSAuthBackendSTSRoleCheck_attrs(backend, accountID, stsRole string)
}
}

func testAccAWSAuthBackendSTSRoleConfig_basic(backend, accountID, stsRole string) string {
return fmt.Sprintf(`
func testAccAWSAuthBackendSTSRoleConfig(backend, accountID, stsRole, externalID string) string {
backendResource := fmt.Sprintf(`
resource "vault_auth_backend" "aws" {
type = "aws"
path = "%s"
}
type = "aws"
path = "%s"
}`, backend)

roleResourceOptionalFields := ""
if externalID != "" {
roleResourceOptionalFields += fmt.Sprintf(`
external_id = "%s"`, externalID)
}

roleResource := fmt.Sprintf(`
resource "vault_aws_auth_backend_sts_role" "role" {
backend = vault_auth_backend.aws.path
account_id = "%s"
sts_role = "%s"
backend = vault_auth_backend.aws.path
account_id = "%s"
sts_role = "%s"%s
}
`, backend, accountID, stsRole)
`, accountID, stsRole, roleResourceOptionalFields)

resources := []string{backendResource, roleResource}

return strings.Join(resources, "\n")
}
18 changes: 18 additions & 0 deletions vault/resource_database_secret_backend_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,12 @@ func postgresConnectionStringResource() *schema.Resource {
Optional: true,
Description: "If set, allows onboarding static roles with a rootless connection configuration.",
}
r.Schema["password_authentication"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "password",
Description: "When set to `scram-sha-256`, passwords will be hashed by Vault before being sent to PostgreSQL.",
}

return r
}
Expand Down Expand Up @@ -1150,6 +1156,12 @@ func getPostgresConnectionDetailsFromResponse(d *schema.ResourceData, prefix str
}
}

if provider.IsAPISupported(meta, provider.VaultVersion114) {
if v, ok := data["password_authentication"]; ok {
result["password_authentication"] = v.(string)
}
}

if provider.IsAPISupported(meta, provider.VaultVersion118) {
if v, ok := data["tls_ca"]; ok {
result["tls_ca"] = v.(string)
Expand Down Expand Up @@ -1571,6 +1583,12 @@ func setPostgresDatabaseConnectionData(d *schema.ResourceData, prefix string, da
}
}

if provider.IsAPISupported(meta, provider.VaultVersion114) {
if v, ok := d.GetOk(prefix + "password_authentication"); ok {
data["password_authentication"] = v.(string)
}
}

if provider.IsAPISupported(meta, provider.VaultVersion118) && provider.IsEnterpriseSupported(meta) {
if v, ok := d.GetOk(prefix + "self_managed"); ok {
data["self_managed"] = v.(bool)
Expand Down
30 changes: 29 additions & 1 deletion vault/resource_database_secret_backend_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ func TestAccDatabaseSecretBackendConnection_postgresql(t *testing.T) {
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "root_rotation_statements.0", "FOOBAR"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "verify_connection", "true"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "postgresql.0.connection_url", connURL),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "postgresql.0.password_authentication", "password"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "postgresql.0.max_open_connections", maxOpenConnections),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "postgresql.0.max_idle_connections", maxIdleConnections),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "postgresql.0.max_connection_lifetime", maxConnLifetime),
Expand All @@ -833,6 +834,12 @@ func TestAccDatabaseSecretBackendConnection_postgresql(t *testing.T) {
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "postgresql.0.username_template", ""),
),
},
{
Config: testAccDatabaseSecretBackendConnectionConfig_postgresql_password_authentication(name, backend, parsedURL),
Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, pluginName,
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "postgresql.0.password_authentication", "scram-sha-256"),
),
},
},
})
}
Expand Down Expand Up @@ -1771,6 +1778,27 @@ resource "vault_database_secret_backend_connection" "test" {
`, path, name, parsedURL.String())
}

func testAccDatabaseSecretBackendConnectionConfig_postgresql_password_authentication(name, path string, parsedURL *url.URL) string {
return fmt.Sprintf(`
resource "vault_mount" "db" {
path = "%s"
type = "database"
}
resource "vault_database_secret_backend_connection" "test" {
backend = vault_mount.db.path
name = "%s"
allowed_roles = ["dev", "prod"]
root_rotation_statements = ["FOOBAR"]
postgresql {
connection_url = "%s"
password_authentication = "scram-sha-256"
}
}
`, path, name, parsedURL.String())
}

func testAccDatabaseSecretBackendConnectionConfig_postgresql_tls(name, path, tlsCA, tlsCert, privateKey string) string {
return fmt.Sprintf(`
resource "vault_mount" "db" {
Expand Down Expand Up @@ -1849,7 +1877,7 @@ resource "vault_database_secret_backend_connection" "test" {
allowed_roles = ["dev", "prod"]
root_rotation_statements = ["FOOBAR"]
snowflake {
snowflake {
connection_url = "%s"
username = "%s"
password = "%s"
Expand Down
Loading

0 comments on commit e63168d

Please sign in to comment.