Skip to content

Commit

Permalink
Update azurerm_traffic_manager_profile - Updating of the profile no…
Browse files Browse the repository at this point in the history
… longer destroys all the endpoints (#7846)

Fixes #6041
Supersedes #7471

Special thanks to @nitzanm

I also updated the test cases, since the relative_name in dns_config block is a ForceNew attribute, therefore it makes no sense to change in an update test case.
  • Loading branch information
ArcturusZhang authored Aug 11, 2020
1 parent 84e6875 commit eb87afb
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmTrafficManagerProfile() *schema.Resource {
return &schema.Resource{
Create: resourceArmTrafficManagerProfileCreateUpdate,
Create: resourceArmTrafficManagerProfileCreate,
Read: resourceArmTrafficManagerProfileRead,
Update: resourceArmTrafficManagerProfileCreateUpdate,
Update: resourceArmTrafficManagerProfileUpdate,
Delete: resourceArmTrafficManagerProfileDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
Expand Down Expand Up @@ -180,29 +179,28 @@ func resourceArmTrafficManagerProfile() *schema.Resource {
}
}

func resourceArmTrafficManagerProfileCreateUpdate(d *schema.ResourceData, meta interface{}) error {
func resourceArmTrafficManagerProfileCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).TrafficManager.ProfilesClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()

log.Printf("[INFO] preparing arguments for TrafficManager Profile creation.")

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)

if features.ShouldResourcesBeImported() && d.IsNewResource() {
existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing TrafficManager profile %s (resource group %s) ID", name, resourceGroup)
}
existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing TrafficManager profile %s (resource group %s) ID", name, resourceGroup)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_traffic_manager_profile", *existing.ID)
}
if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_traffic_manager_profile", *existing.ID)
}

// No existing profile - start from a new struct.
profile := trafficmanager.Profile{
Name: &name,
Location: utils.String("global"), // must be provided in request
Expand Down Expand Up @@ -279,6 +277,48 @@ func resourceArmTrafficManagerProfileRead(d *schema.ResourceData, meta interface
return tags.FlattenAndSet(d, resp.Tags)
}

func resourceArmTrafficManagerProfileUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).TrafficManager.ProfilesClient
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := azure.ParseAzureResourceID(d.Id())
if err != nil {
return err
}
resourceGroup := id.ResourceGroup
name := id.Path["trafficManagerProfiles"]

update := trafficmanager.Profile{
ProfileProperties: &trafficmanager.ProfileProperties{},
}
if d.HasChange("tags") {
update.Tags = tags.Expand(d.Get("tags").(map[string]interface{}))
}

if d.HasChange("profile_status") {
update.ProfileProperties.ProfileStatus = trafficmanager.ProfileStatus(d.Get("profile_status").(string))
}

if d.HasChange("traffic_routing_method") {
update.ProfileProperties.TrafficRoutingMethod = trafficmanager.TrafficRoutingMethod(d.Get("traffic_routing_method").(string))
}

if d.HasChange("dns_config") {
update.ProfileProperties.DNSConfig = expandArmTrafficManagerDNSConfig(d)
}

if d.HasChange("monitor_config") {
update.ProfileProperties.MonitorConfig = expandArmTrafficManagerMonitorConfig(d)
}

if _, err := client.Update(ctx, resourceGroup, name, update); err != nil {
return fmt.Errorf("Error updating TrafficManager profile %q (resource group %q): %+v", name, resourceGroup, err)
}

return resourceArmTrafficManagerProfileRead(d, meta)
}

func resourceArmTrafficManagerProfileDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).TrafficManager.ProfilesClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,32 @@ func TestAccAzureRMTrafficManagerProfile_update(t *testing.T) {
})
}

func TestAccAzureRMTrafficManagerProfile_updateEnsureDoNotEraseEndpoints(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_traffic_manager_profile", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMTrafficManagerProfileDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMTrafficManagerProfile_completeWithEndpoint(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMTrafficManagerProfileExists(data.ResourceName),
),
},
data.ImportStep(),
{
Config: testAccAzureRMTrafficManagerProfile_completeUpdatedWithEndpoint(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMTrafficManagerProfileExists(data.ResourceName),
),
},
data.ImportStep(),
},
})
}

func TestAccAzureRMTrafficManagerProfile_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_traffic_manager_profile", "test")
resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -228,24 +254,31 @@ func testCheckAzureRMTrafficManagerProfileDestroy(s *terraform.State) error {
return nil
}

func testAccAzureRMTrafficManagerProfile_basic(data acceptance.TestData, method string) string {
func testAccAzureRMTrafficManagerProfile_template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-traffic-%[1]d"
location = "%[2]s"
name = "acctestRG-traffic-%d"
location = "%s"
}
`, data.RandomInteger, data.Locations.Primary)
}

func testAccAzureRMTrafficManagerProfile_basic(data acceptance.TestData, method string) string {
template := testAccAzureRMTrafficManagerProfile_template(data)
return fmt.Sprintf(`
%s
resource "azurerm_traffic_manager_profile" "test" {
name = "acctest-TMP-%[1]d"
name = "acctest-TMP-%d"
resource_group_name = azurerm_resource_group.test.name
traffic_routing_method = "%[3]s"
traffic_routing_method = "%s"
dns_config {
relative_name = "acctest-tmp-%[1]d"
relative_name = "acctest-tmp-%d"
ttl = 30
}
Expand All @@ -255,7 +288,7 @@ resource "azurerm_traffic_manager_profile" "test" {
path = "/"
}
}
`, data.RandomInteger, data.Locations.Primary, method)
`, template, data.RandomInteger, method, data.RandomInteger)
}

func testAccAzureRMTrafficManagerProfile_requiresImport(data acceptance.TestData) string {
Expand Down Expand Up @@ -283,15 +316,9 @@ resource "azurerm_traffic_manager_profile" "import" {
}

func testAccAzureRMTrafficManagerProfile_complete(data acceptance.TestData) string {
template := testAccAzureRMTrafficManagerProfile_template(data)
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-traffic-%d"
location = "%s"
}
%s
resource "azurerm_traffic_manager_profile" "test" {
name = "acctest-TMP-%d"
Expand Down Expand Up @@ -327,27 +354,121 @@ resource "azurerm_traffic_manager_profile" "test" {
cost_center = "acctest"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
`, template, data.RandomInteger, data.RandomInteger)
}

func testAccAzureRMTrafficManagerProfile_completeUpdated(data acceptance.TestData) string {
template := testAccAzureRMTrafficManagerProfile_template(data)
return fmt.Sprintf(`
provider "azurerm" {
features {}
%s
resource "azurerm_traffic_manager_profile" "test" {
name = "acctest-TMP-%d"
resource_group_name = azurerm_resource_group.test.name
traffic_routing_method = "Priority"
dns_config {
relative_name = "acctest-tmp-%d"
ttl = 30
}
monitor_config {
expected_status_code_ranges = [
"302-304",
]
custom_header {
name = "foo2"
value = "bar2"
}
protocol = "https"
port = 442
path = "/"
interval_in_seconds = 30
timeout_in_seconds = 6
tolerated_number_of_failures = 3
}
tags = {
Environment = "staging"
}
}
`, template, data.RandomInteger, data.RandomInteger)
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-traffic-%d"
location = "%s"
func testAccAzureRMTrafficManagerProfile_endpointResource(data acceptance.TestData) string {
return fmt.Sprintf(`
resource "azurerm_traffic_manager_endpoint" "test" {
name = "acctestend-external%d"
resource_group_name = azurerm_resource_group.test.name
profile_name = azurerm_traffic_manager_profile.test.name
target = "terraform.io"
type = "externalEndpoints"
weight = 100
}
`, data.RandomInteger)
}

func testAccAzureRMTrafficManagerProfile_completeWithEndpoint(data acceptance.TestData) string {
template := testAccAzureRMTrafficManagerProfile_template(data)
endpoint := testAccAzureRMTrafficManagerProfile_endpointResource(data)
return fmt.Sprintf(`
%s
resource "azurerm_traffic_manager_profile" "test" {
name = "acctest-TMP-%d"
resource_group_name = azurerm_resource_group.test.name
traffic_routing_method = "Weighted"
dns_config {
relative_name = "acctest-tmp-%d"
ttl = 30
}
monitor_config {
expected_status_code_ranges = [
"100-101",
"301-303",
]
custom_header {
name = "foo"
value = "bar"
}
protocol = "tcp"
port = 777
interval_in_seconds = 30
timeout_in_seconds = 9
tolerated_number_of_failures = 6
}
tags = {
Environment = "Production"
cost_center = "acctest"
}
}
%s
`, template, data.RandomInteger, data.RandomInteger, endpoint)
}

func testAccAzureRMTrafficManagerProfile_completeUpdatedWithEndpoint(data acceptance.TestData) string {
template := testAccAzureRMTrafficManagerProfile_template(data)
endpoint := testAccAzureRMTrafficManagerProfile_endpointResource(data)
return fmt.Sprintf(`
%s
resource "azurerm_traffic_manager_profile" "test" {
name = "acctest-TMP-%d"
resource_group_name = azurerm_resource_group.test.name
traffic_routing_method = "Priority"
dns_config {
relative_name = "acctest-tmp-rename-%d"
relative_name = "acctest-tmp-%d"
ttl = 30
}
Expand All @@ -374,19 +495,15 @@ resource "azurerm_traffic_manager_profile" "test" {
Environment = "staging"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
%s
`, template, data.RandomInteger, data.RandomInteger, endpoint)
}

func testAccAzureRMTrafficManagerProfile_failoverError(data acceptance.TestData) string {
template := testAccAzureRMTrafficManagerProfile_template(data)
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-traffic-%d"
location = "%s"
}
%s
resource "azurerm_traffic_manager_profile" "test" {
name = "acctest-TMP-%d"
Expand All @@ -407,5 +524,5 @@ resource "azurerm_traffic_manager_profile" "test" {
tolerated_number_of_failures = 3
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
`, template, data.RandomInteger, data.RandomInteger)
}

0 comments on commit eb87afb

Please sign in to comment.