Skip to content

Commit

Permalink
Restore azurerm_nginx_configuration resource and data source (#25773)
Browse files Browse the repository at this point in the history
* Revert "`Nginx`: embed nginx configuration into deployment resource (#24276)"

This reverts commit 7a1f9f7.

* deprecate configuration field in deployment resource

* add https use case test with certs and config and fix lint

* fix MissingManagedIdentity error in nginx tests

The NGINXaaS API now requires a managed identity to be added to the depoyment if metrics are enabled.
This updates tests which do not have an identity to set diagnose_support_enabled to false.

* fix azurerm_nginx_configuration data source test

Now that the NGINXaaS API does not provide a default config, we need to ensure the resource gets created
before referencing the data source, so we don't get config not found errors.
  • Loading branch information
valyria257 authored Jun 4, 2024
1 parent d052716 commit 4508704
Show file tree
Hide file tree
Showing 9 changed files with 644 additions and 282 deletions.
2 changes: 1 addition & 1 deletion internal/services/nginx/nginx_certificate_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ resource "azurerm_nginx_deployment" "test" {
resource_group_name = azurerm_resource_group.test.name
sku = "standard_Monthly"
location = azurerm_resource_group.test.location
diagnose_support_enabled = true
diagnose_support_enabled = false
identity {
type = "UserAssigned"
Expand Down
41 changes: 41 additions & 0 deletions internal/services/nginx/nginx_configuration_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package nginx_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
)

type NginxConfigurationDataSource struct{}

func TestAccNginxConfigurationDataSource_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_nginx_configuration", "test")
r := NginxConfigurationDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("root_file").Exists(),
check.That(data.ResourceName).Key("config_file.0.content").Exists(),
),
},
})
}

func (d NginxConfigurationDataSource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
data "azurerm_nginx_configuration" "test" {
nginx_deployment_id = azurerm_nginx_deployment.test.id
depends_on = [azurerm_nginx_configuration.test]
}
`, ConfigurationResource{}.basic(data))
}
8 changes: 0 additions & 8 deletions internal/services/nginx/nginx_configuration_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,7 @@ func (c ConfigurationModel) ToSDKModel() nginxconfiguration.NginxConfiguration {

type ConfigurationResource struct{}

// This resource has been deprecated and will be removed in the next major release.
// Default Nginx Configuration cannot be created anymore for service API breaking change created it automatically
// nginx configuration block is now embedded into nginx deployment resource
func (m *ConfigurationResource) DeprecatedInFavourOfResource() string {
return "azurerm_nginx_deployment"
}

var _ sdk.Resource = (*ConfigurationResource)(nil)
var _ sdk.ResourceWithDeprecationReplacedBy = &ConfigurationResource{}

func (m ConfigurationResource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
Expand Down
305 changes: 305 additions & 0 deletions internal/services/nginx/nginx_configuration_resource_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package nginx_test

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/resource-manager/nginx/2024-01-01-preview/nginxconfiguration"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/nginx"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
)

type ConfigurationResource struct{}

func (a ConfigurationResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := nginxconfiguration.ParseConfigurationID(state.ID)
if err != nil {
return nil, err
}
resp, err := client.Nginx.NginxConfiguration.ConfigurationsGet(ctx, *id)
if err != nil {
return nil, fmt.Errorf("retrieving %s: %+v", id, err)
}
return pointer.To(resp.Model != nil), nil
}

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

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

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

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

func (a ConfigurationResource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_nginx_configuration" "test" {
nginx_deployment_id = azurerm_nginx_deployment.test.id
root_file = "/etc/nginx/nginx.conf"
config_file {
content = local.config_content
virtual_path = "/etc/nginx/nginx.conf"
}
protected_file {
content = local.protected_content
virtual_path = "/opt/.htpasswd"
}
}
`, a.template(data))
}

func (a ConfigurationResource) withCertificate(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
locals {
config_content = base64encode(<<-EOT
http {
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/test.crt;
ssl_certificate_key /etc/nginx/ssl/test.key;
location / {
return 200 "Hello World";
}
}
}
EOT
)
}
resource "azurerm_nginx_certificate" "test" {
name = "acctest"
nginx_deployment_id = azurerm_nginx_deployment.test.id
key_virtual_path = "/etc/nginx/ssl/test.key"
certificate_virtual_path = "/etc/nginx/ssl/test.crt"
key_vault_secret_id = azurerm_key_vault_certificate.test.secret_id
}
resource "azurerm_nginx_configuration" "test" {
nginx_deployment_id = azurerm_nginx_deployment.test.id
root_file = "/etc/nginx/nginx.conf"
config_file {
content = local.config_content
virtual_path = "/etc/nginx/nginx.conf"
}
depends_on = [azurerm_nginx_certificate.test]
}
`, CertificateResource{}.template(data))
}

func (a ConfigurationResource) requiresImport(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_nginx_configuration" "import" {
nginx_deployment_id = azurerm_nginx_configuration.test.nginx_deployment_id
root_file = azurerm_nginx_configuration.test.root_file
config_file {
content = base64encode("http{}")
virtual_path = "/"
}
}
`, a.basic(data))
}

func (a ConfigurationResource) update(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_nginx_configuration" "test" {
nginx_deployment_id = azurerm_nginx_deployment.test.id
root_file = "/etc/nginx/nginx.conf"
config_file {
content = local.config_content
virtual_path = "/etc/nginx/nginx.conf"
}
config_file {
content = local.sub_config_content
virtual_path = "/etc/nginx/site/b.conf"
}
protected_file {
content = local.protected_content
virtual_path = "/opt/.htpasswd"
}
}
`, a.template(data))
}

func (a ConfigurationResource) template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-auto-%[1]d"
location = "%[2]s"
}
locals {
config_content = base64encode(<<-EOT
http {
server {
listen 80;
location / {
auth_basic "Protected Area";
auth_basic_user_file /opt/.htpasswd;
default_type text/html;
return 200 '<!doctype html><html lang="en"><head></head><body>
<div>this one will be updated</div>
<div>at 10:38 am</div>
</body></html>';
}
include site/*.conf;
}
}
EOT
)
protected_content = base64encode(<<-EOT
user:$apr1$VeUA5kt.$IjjRk//8miRxDsZvD4daF1
EOT
)
sub_config_content = base64encode(<<-EOT
location /bbb {
default_type text/html;
return 200 '<!doctype html><html lang="en"><head></head><body>
<div>this one will be updated</div>
<div>at 10:38 am</div>
</body></html>';
}
EOT
)
}
resource "azurerm_public_ip" "test" {
name = "acctest%[1]d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
allocation_method = "Static"
sku = "Standard"
tags = {
environment = "Production"
}
}
resource "azurerm_virtual_network" "test" {
name = "acctestvirtnet%[1]d"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
}
resource "azurerm_subnet" "test" {
name = "accsubnet%[1]d"
resource_group_name = azurerm_resource_group.test.name
virtual_network_name = azurerm_virtual_network.test.name
address_prefixes = ["10.0.2.0/24"]
delegation {
name = "delegation"
service_delegation {
name = "NGINX.NGINXPLUS/nginxDeployments"
actions = [
"Microsoft.Network/virtualNetworks/subnets/join/action",
]
}
}
}
resource "azurerm_nginx_deployment" "test" {
name = "acctest-%[1]d"
resource_group_name = azurerm_resource_group.test.name
sku = "standard_Monthly"
location = azurerm_resource_group.test.location
diagnose_support_enabled = false
frontend_public {
ip_address = [azurerm_public_ip.test.id]
}
network_interface {
subnet_id = azurerm_subnet.test.id
}
tags = {
foo = "bar"
}
}
`, data.RandomInteger, data.Locations.Primary)
}
Loading

0 comments on commit 4508704

Please sign in to comment.