@@ -12,8 +12,8 @@ import (
1212 "github.com/hashicorp/go-azure-helpers/lang/pointer"
1313 "github.com/hashicorp/go-azure-helpers/lang/response"
1414 "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
15- "github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-09-01/publicipprefixes"
1615 "github.com/hashicorp/go-azure-sdk/resource-manager/network/2025-01-01/natgateways"
16+ "github.com/hashicorp/go-azure-sdk/resource-manager/network/2025-01-01/publicipprefixes"
1717 "github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
1818 "github.com/hashicorp/terraform-provider-azurerm/internal/clients"
1919 "github.com/hashicorp/terraform-provider-azurerm/internal/locks"
@@ -71,8 +71,8 @@ func resourceNATGatewayPublicIpPrefixAssociationCreate(d *pluginsdk.ResourceData
7171 return err
7272 }
7373
74- locks .ByName (natGatewayId .NatGatewayName , natGatewayResourceName )
75- defer locks .UnlockByName (natGatewayId .NatGatewayName , natGatewayResourceName )
74+ locks .ByID (natGatewayId .ID () )
75+ defer locks .UnlockByID (natGatewayId .ID () )
7676
7777 natGateway , err := client .Get (ctx , * natGatewayId , natgateways .DefaultGetOperationOptions ())
7878 if err != nil {
@@ -89,27 +89,42 @@ func resourceNATGatewayPublicIpPrefixAssociationCreate(d *pluginsdk.ResourceData
8989 return fmt .Errorf ("retrieving %s: `properties` was nil" , natGatewayId )
9090 }
9191
92- id := commonids .NewCompositeResourceID (natGatewayId , publicIpPrefixId )
93-
94- publicIpPrefixes := make ([]natgateways.SubResource , 0 )
95- if natGateway .Model .Properties .PublicIPPrefixes != nil {
96- for _ , existingPublicIPPrefix := range * natGateway .Model .Properties .PublicIPPrefixes {
97- if existingPublicIPPrefix .Id == nil {
98- continue
99- }
92+ publicIpPrefix , err := meta .(* clients.Client ).Network .PublicIPPrefixes .Get (ctx , * publicIpPrefixId , publicipprefixes .DefaultGetOperationOptions ())
93+ if err != nil {
94+ if response .WasNotFound (publicIpPrefix .HttpResponse ) {
95+ return fmt .Errorf ("%s was not found" , publicIpPrefixId )
96+ }
97+ return fmt .Errorf ("retrieving %s: %+v" , publicIpPrefixId , err )
98+ }
99+ if publicIpPrefix .Model == nil {
100+ return fmt .Errorf ("retrieving %s: `model` was nil" , publicIpPrefixId )
101+ }
102+ if publicIpPrefix .Model .Properties == nil {
103+ return fmt .Errorf ("retrieving %s: `properties` was nil" , publicIpPrefixId )
104+ }
100105
101- if strings .EqualFold (* existingPublicIPPrefix .Id , publicIpPrefixId .ID ()) {
102- return tf .ImportAsExistsError ("azurerm_nat_gateway_public_ip_prefix_association" , id .ID ())
103- }
106+ isIPv6 := pointer .From (publicIpPrefix .Model .Properties .PublicIPAddressVersion ) == publicipprefixes .IPVersionIPvSix
107+ id := commonids .NewCompositeResourceID (natGatewayId , publicIpPrefixId )
104108
105- publicIpPrefixes = append (publicIpPrefixes , existingPublicIPPrefix )
109+ gatewayProperties := natGateway .Model .Properties
110+ publicIpPrefixes := pointer .From (gatewayProperties .PublicIPPrefixes )
111+ if isIPv6 {
112+ publicIpPrefixes = pointer .From (gatewayProperties .PublicIPPrefixesV6 )
113+ }
114+ for _ , existingPublicIPPrefix := range publicIpPrefixes {
115+ if strings .EqualFold (pointer .From (existingPublicIPPrefix .Id ), publicIpPrefixId .ID ()) {
116+ return tf .ImportAsExistsError ("azurerm_nat_gateway_public_ip_prefix_association" , id .ID ())
106117 }
107118 }
108119
109120 publicIpPrefixes = append (publicIpPrefixes , natgateways.SubResource {
110121 Id : pointer .To (publicIpPrefixId .ID ()),
111122 })
112- natGateway .Model .Properties .PublicIPPrefixes = & publicIpPrefixes
123+ if isIPv6 {
124+ gatewayProperties .PublicIPPrefixesV6 = pointer .To (publicIpPrefixes )
125+ } else {
126+ gatewayProperties .PublicIPPrefixes = pointer .To (publicIpPrefixes )
127+ }
113128
114129 if err := client .CreateOrUpdateThenPoll (ctx , * natGatewayId , * natGateway .Model ); err != nil {
115130 return fmt .Errorf ("updating %s: %+v" , natGatewayId , err )
@@ -140,32 +155,16 @@ func resourceNATGatewayPublicIpPrefixAssociationRead(d *pluginsdk.ResourceData,
140155 return fmt .Errorf ("retrieving %s: %+v" , id .First , err )
141156 }
142157
143- if model := natGateway .Model ; model != nil {
144- if props := model .Properties ; props != nil {
145- if props .PublicIPPrefixes == nil {
146- log .Printf ("[DEBUG] %s doesn't have any Public IP Prefixes - removing from state!" , id .First )
147- d .SetId ("" )
148- return nil
149- }
150-
151- publicIPPrefixId := ""
152- for _ , pipp := range * props .PublicIPPrefixes {
153- if pipp .Id == nil {
154- continue
155- }
156-
157- if strings .EqualFold (* pipp .Id , id .Second .ID ()) {
158- publicIPPrefixId = * pipp .Id
159- break
160- }
161- }
162-
163- if publicIPPrefixId == "" {
164- log .Printf ("[DEBUG] Association between %s and %s was not found - removing from state" , id .First , id .Second )
165- d .SetId ("" )
166- return nil
167- }
168- }
158+ if natGateway .Model == nil {
159+ return fmt .Errorf ("retrieving %s: `model` was nil" , id .First )
160+ }
161+ if natGateway .Model .Properties == nil {
162+ return fmt .Errorf ("retrieving %s: `properties` was nil" , id .First )
163+ }
164+ if ! natGatewayPublicIpPrefixAssociationExists (natGateway .Model .Properties , id .Second .ID ()) {
165+ log .Printf ("[DEBUG] Association between %s and %s was not found - removing from state" , id .First , id .Second )
166+ d .SetId ("" )
167+ return nil
169168 }
170169
171170 d .Set ("nat_gateway_id" , id .First .ID ())
@@ -184,8 +183,8 @@ func resourceNATGatewayPublicIpPrefixAssociationDelete(d *pluginsdk.ResourceData
184183 return err
185184 }
186185
187- locks .ByName (id .First .NatGatewayName , natGatewayResourceName )
188- defer locks .UnlockByName (id .First .NatGatewayName , natGatewayResourceName )
186+ locks .ByID (id .First .ID () )
187+ defer locks .UnlockByID (id .First .ID () )
189188
190189 natGateway , err := client .Get (ctx , * id .First , natgateways .DefaultGetOperationOptions ())
191190 if err != nil {
@@ -202,23 +201,64 @@ func resourceNATGatewayPublicIpPrefixAssociationDelete(d *pluginsdk.ResourceData
202201 return fmt .Errorf ("retrieving %s: `properties` was nil" , id .First )
203202 }
204203
205- publicIpPrefixes := make ([]natgateways.SubResource , 0 )
206- if publicIPPrefixes := natGateway .Model .Properties .PublicIPPrefixes ; publicIPPrefixes != nil {
207- for _ , publicIPPrefix := range * publicIPPrefixes {
208- if publicIPPrefix .Id == nil {
209- continue
210- }
211-
212- if ! strings .EqualFold (* publicIPPrefix .Id , id .Second .ID ()) {
213- publicIpPrefixes = append (publicIpPrefixes , publicIPPrefix )
214- }
215- }
204+ if ! removeNATGatewayPublicIpPrefixAssociation (natGateway .Model .Properties , id .Second .ID ()) {
205+ return nil
216206 }
217- natGateway .Model .Properties .PublicIPPrefixes = & publicIpPrefixes
218207
219208 if err := client .CreateOrUpdateThenPoll (ctx , * id .First , * natGateway .Model ); err != nil {
220- return fmt .Errorf ("removing association between %s and %s : %+v" , id . First , id . Second , err )
209+ return fmt .Errorf ("deleting %s : %+v" , id , err )
221210 }
222211
223212 return nil
224213}
214+
215+ func natGatewayPublicIpPrefixAssociationExists (properties * natgateways.NatGatewayPropertiesFormat , publicIpPrefixId string ) bool {
216+ if properties == nil {
217+ return false
218+ }
219+
220+ for _ , publicIpPrefix := range pointer .From (properties .PublicIPPrefixes ) {
221+ if strings .EqualFold (pointer .From (publicIpPrefix .Id ), publicIpPrefixId ) {
222+ return true
223+ }
224+ }
225+
226+ for _ , publicIpPrefix := range pointer .From (properties .PublicIPPrefixesV6 ) {
227+ if strings .EqualFold (pointer .From (publicIpPrefix .Id ), publicIpPrefixId ) {
228+ return true
229+ }
230+ }
231+
232+ return false
233+ }
234+
235+ func removeNATGatewayPublicIpPrefixAssociation (properties * natgateways.NatGatewayPropertiesFormat , publicIpPrefixId string ) bool {
236+ if properties == nil {
237+ return false
238+ }
239+
240+ removed := false
241+ updatedIPv4Prefixes := make ([]natgateways.SubResource , 0 )
242+ for _ , publicIpPrefix := range pointer .From (properties .PublicIPPrefixes ) {
243+ if strings .EqualFold (pointer .From (publicIpPrefix .Id ), publicIpPrefixId ) {
244+ removed = true
245+ continue
246+ }
247+
248+ updatedIPv4Prefixes = append (updatedIPv4Prefixes , publicIpPrefix )
249+ }
250+ properties .PublicIPPrefixes = pointer .To (updatedIPv4Prefixes )
251+
252+ updatedIPv6Prefixes := make ([]natgateways.SubResource , 0 )
253+ for _ , publicIpPrefix := range pointer .From (properties .PublicIPPrefixesV6 ) {
254+ if strings .EqualFold (pointer .From (publicIpPrefix .Id ), publicIpPrefixId ) {
255+ removed = true
256+ continue
257+ }
258+
259+ updatedIPv6Prefixes = append (updatedIPv6Prefixes , publicIpPrefix )
260+ }
261+ properties .PublicIPPrefixesV6 = pointer .To (updatedIPv6Prefixes )
262+
263+ return removed
264+ }
0 commit comments