Skip to content

Commit

Permalink
azurerm_redis_cache: access_keys_authentication_disabled property (ha…
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerry Tan authored and gerrytan committed Aug 14, 2024
1 parent 8ab553c commit 199cea6
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 3 deletions.
7 changes: 7 additions & 0 deletions internal/services/redis/redis_cache_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ func dataSourceRedisCache() *pluginsdk.Resource {
Sensitive: true,
},

"access_keys_authentication_disabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"tags": commonschema.TagsDataSource(),
},
}
Expand Down Expand Up @@ -344,6 +349,8 @@ func dataSourceRedisCacheRead(d *pluginsdk.ResourceData, meta interface{}) error
d.Set("primary_connection_string", getRedisConnectionString(*props.HostName, *props.SslPort, *keys.Model.PrimaryKey, enableSslPort))
d.Set("secondary_connection_string", getRedisConnectionString(*props.HostName, *props.SslPort, *keys.Model.SecondaryKey, enableSslPort))

d.Set("access_keys_authentication_disabled", *props.DisableAccessKeyAuthentication)

if err := tags.FlattenAndSet(d, model.Tags); err != nil {
return fmt.Errorf("setting `tags`: %+v", err)
}
Expand Down
1 change: 1 addition & 0 deletions internal/services/redis/redis_cache_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestAccRedisCacheDataSource_standard(t *testing.T) {
check.That(data.ResourceName).Key("tags.environment").HasValue("production"),
check.That(data.ResourceName).Key("primary_connection_string").Exists(),
check.That(data.ResourceName).Key("secondary_connection_string").Exists(),
check.That(data.ResourceName).Key("access_keys_authentication_disabled").Exists(),
),
},
})
Expand Down
21 changes: 18 additions & 3 deletions internal/services/redis/redis_cache_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,11 @@ func resourceRedisCache() *pluginsdk.Resource {
},
},

"access_keys_authentication_disabled": {
Type: pluginsdk.TypeBool,
Optional: true,
},

"tags": commonschema.Tags(),
},

Expand All @@ -376,6 +381,12 @@ func resourceRedisCache() *pluginsdk.Resource {
}
return false
}),
pluginsdk.CustomizeDiffShim(func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error {
return validate.ValidateAccessKeysAuth(
diff.Get("access_keys_authentication_disabled").(bool),
diff.Get("redis_configuration.0.active_directory_authentication_enabled").(bool),
)
}),
),
}

Expand Down Expand Up @@ -499,7 +510,8 @@ func resourceRedisCacheCreate(d *pluginsdk.ResourceData, meta interface{}) error
parameters := redis.RedisCreateParameters{
Location: location.Normalize(d.Get("location").(string)),
Properties: redis.RedisCreateProperties{
EnableNonSslPort: pointer.To(enableNonSslPort.(bool)),
DisableAccessKeyAuthentication: pointer.To(d.Get("access_keys_authentication_disabled").(bool)),
EnableNonSslPort: pointer.To(enableNonSslPort.(bool)),
Sku: redis.Sku{
Capacity: int64(d.Get("capacity").(int)),
Family: redis.SkuFamily(d.Get("family").(string)),
Expand Down Expand Up @@ -613,8 +625,9 @@ func resourceRedisCacheUpdate(d *pluginsdk.ResourceData, meta interface{}) error

parameters := redis.RedisUpdateParameters{
Properties: &redis.RedisUpdateProperties{
MinimumTlsVersion: pointer.To(redis.TlsVersion(d.Get("minimum_tls_version").(string))),
EnableNonSslPort: pointer.To(enableNonSslPort.(bool)),
DisableAccessKeyAuthentication: pointer.To(d.Get("access_keys_authentication_disabled").(bool)),
MinimumTlsVersion: pointer.To(redis.TlsVersion(d.Get("minimum_tls_version").(string))),
EnableNonSslPort: pointer.To(enableNonSslPort.(bool)),
Sku: &redis.Sku{
Capacity: int64(d.Get("capacity").(int)),
Family: redis.SkuFamily(d.Get("family").(string)),
Expand Down Expand Up @@ -837,6 +850,8 @@ func resourceRedisCacheRead(d *pluginsdk.ResourceData, meta interface{}) error {
d.Set("primary_access_key", keysResp.Model.PrimaryKey)
d.Set("secondary_access_key", keysResp.Model.SecondaryKey)

d.Set("access_keys_authentication_disabled", props.DisableAccessKeyAuthentication)

if err := tags.FlattenAndSet(d, model.Tags); err != nil {
return fmt.Errorf("setting `tags`: %+v", err)
}
Expand Down
57 changes: 57 additions & 0 deletions internal/services/redis/redis_cache_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,35 @@ func TestAccRedisCache_SkuDowngrade(t *testing.T) {
})
}

func TestAccRedisCache_AccessKeysAuthenticationEnabledDisabled(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_redis_cache", "test")
r := RedisCacheResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.accessKeysAuthentication(data, false, false),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.accessKeysAuthentication(data, true, true),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.accessKeysAuthentication(data, false, false),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func (t RedisCacheResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := redis.ParseRediID(state.ID)
if err != nil {
Expand Down Expand Up @@ -1594,3 +1623,31 @@ resource "azurerm_redis_cache" "test" {
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (RedisCacheResource) accessKeysAuthentication(data acceptance.TestData, accessKeysAuthenticationDisabled bool, activeDirectoryAuthenticationEnabled bool) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_redis_cache" "test" {
name = "acctestRedis-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
capacity = 1
family = "C"
sku_name = "Basic"
non_ssl_port_enabled = false
minimum_tls_version = "1.2"
access_keys_authentication_disabled = %t
redis_configuration {
active_directory_authentication_enabled = %t
}
}`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, accessKeysAuthenticationDisabled, accessKeysAuthenticationDisabled)
}
18 changes: 18 additions & 0 deletions internal/services/redis/validate/access_keys_auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package validate

import (
"fmt"
"log"
)

// Entra (AD) auth has to be set to disable access keys auth
// https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-azure-active-directory-for-authentication
func ValidateAccessKeysAuth(accessKeysAuthenticationDisabled bool, activeDirectoryAuthenticationEnabled bool) error {
log.Printf("[DEBUG] ValidateAccessKeysAuth: accessKeysAuthenticationDisabled: %v, activeDirectoryAuthenticationEnabled: %v", accessKeysAuthenticationDisabled, activeDirectoryAuthenticationEnabled)

if accessKeysAuthenticationDisabled && !activeDirectoryAuthenticationEnabled {
return fmt.Errorf("microsoft entra authorization (active_directory_authentication_enabled) must be enabled in order to disable access key authentication (access_keys_authentication_disabled): https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-azure-active-directory-for-authentication#disable-access-key-authentication-on-your-cache")
}

return nil
}
17 changes: 17 additions & 0 deletions internal/services/redis/validate/access_keys_auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package validate

import (
"testing"
)

func TestValidateAccessKeysAuth_valid(t *testing.T) {
if err := ValidateAccessKeysAuth(true, true); err != nil {
t.Fatalf("Should be valid if accessKeysAuthenticationDisabled: true and activeDirectoryAuthenticationEnabled: true but got error: %v", err)
}
}

func TestValidateAccessKeysAuth_invalid(t *testing.T) {
if err := ValidateAccessKeysAuth(true, false); err == nil {
t.Fatalf("Should return error if accessKeysAuthenticationDisabled: true and activeDirectoryAuthenticationEnabled: false")
}
}
2 changes: 2 additions & 0 deletions website/docs/d/redis_cache.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ output "hostname" {

* `secondary_connection_string` - The secondary connection string of the Redis Instance.

* `access_keys_authentication_disabled` - Whether access key authentication is disabled.

* `redis_configuration` - A `redis_configuration` block as defined below.

* `zones` - A list of Availability Zones in which this Redis Cache is located.
Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/redis_cache.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ The following arguments are supported:

---

* `access_keys_authentication_disabled` - (Optional) Disable access key authentication. Microsoft Entra (AAD) authentication (`active_directory_authentication_enabled`) must be enabled to disable this. Defaults to `false`.

* `enable_non_ssl_port` - (Optional) Enable the non-SSL port (6379) - disabled by default.

* `identity` - (Optional) An `identity` block as defined below.
Expand Down

0 comments on commit 199cea6

Please sign in to comment.