Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_function_app - support for ip_restriction #5440

Merged
merged 9 commits into from
Feb 11, 2020
108 changes: 102 additions & 6 deletions azurerm/internal/services/web/resource_arm_function_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"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/helpers/validate"
"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"
Expand Down Expand Up @@ -225,6 +226,26 @@ func resourceArmFunctionApp() *schema.Resource {
Optional: true,
Default: false,
},
"ip_restriction": {
Type: schema.TypeList,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a TypeSet to prevent duplicates & order won't matter here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying to change to a TypeSet but it is not working as intended. In my case it will take some time to resolve.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shoul just be a matter of changing how you cast the objects, if you grant me push permissions i'll happily make the change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have granted push permission, you can freely add commits to this Pull Request. I tried #5319 for a similar change, but was investigating because the plan no longer worked.

Optional: true,
Computed: true,
ConfigMode: schema.SchemaConfigModeAttr,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip_address": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validate.NoEmptyStrings,
},
"subnet_id": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validate.NoEmptyStrings,
},
},
},
},
"min_tls_version": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -324,7 +345,11 @@ func resourceArmFunctionAppCreate(d *schema.ResourceData, meta interface{}) erro

basicAppSettings := getBasicFunctionAppAppSettings(d, appServiceTier)

siteConfig := expandFunctionAppSiteConfig(d)
siteConfig, err := expandFunctionAppSiteConfig(d)
if err != nil {
return fmt.Errorf("Error expanding `site_config` for Function App %q (Resource Group %q): %s", name, resourceGroup, err)
}

siteConfig.AppSettings = &basicAppSettings

siteEnvelope := web.Site{
Expand Down Expand Up @@ -407,7 +432,10 @@ func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) erro
return err
}
basicAppSettings := getBasicFunctionAppAppSettings(d, appServiceTier)
siteConfig := expandFunctionAppSiteConfig(d)
siteConfig, err := expandFunctionAppSiteConfig(d)
if err != nil {
return fmt.Errorf("Error expanding `site_config` for Function App %q (Resource Group %q): %s", name, resGroup, err)
}

siteConfig.AppSettings = &basicAppSettings

Expand Down Expand Up @@ -450,7 +478,10 @@ func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) erro
}

if d.HasChange("site_config") {
siteConfig := expandFunctionAppSiteConfig(d)
siteConfig, err := expandFunctionAppSiteConfig(d)
if err != nil {
return fmt.Errorf("Error expanding `site_config` for Function App %q (Resource Group %q): %s", name, resGroup, err)
}
siteConfigResource := web.SiteConfigResource{
SiteConfig: &siteConfig,
}
Expand Down Expand Up @@ -706,12 +737,12 @@ func expandFunctionAppAppSettings(d *schema.ResourceData, appServiceTier string)
return output
}

func expandFunctionAppSiteConfig(d *schema.ResourceData) web.SiteConfig {
func expandFunctionAppSiteConfig(d *schema.ResourceData) (web.SiteConfig, error) {
configs := d.Get("site_config").([]interface{})
siteConfig := web.SiteConfig{}

if len(configs) == 0 {
return siteConfig
return siteConfig, nil
}

config := configs[0].(map[string]interface{})
Expand Down Expand Up @@ -746,6 +777,15 @@ func expandFunctionAppSiteConfig(d *schema.ResourceData) web.SiteConfig {
siteConfig.HTTP20Enabled = utils.Bool(v.(bool))
}

if v, ok := config["ip_restriction"]; ok {
ipSecurityRestrictions := v.(interface{})
restrictions, err := expandFunctionAppIpRestriction(ipSecurityRestrictions)
if err != nil {
return siteConfig, err
}
siteConfig.IPSecurityRestrictions = &restrictions
}

if v, ok := config["min_tls_version"]; ok {
siteConfig.MinTLSVersion = web.SupportedTLSVersions(v.(string))
}
Expand All @@ -754,7 +794,7 @@ func expandFunctionAppSiteConfig(d *schema.ResourceData) web.SiteConfig {
siteConfig.FtpsState = web.FtpsState(v.(string))
}

return siteConfig
return siteConfig, nil
}

func flattenFunctionAppSiteConfig(input *web.SiteConfig) []interface{} {
Expand Down Expand Up @@ -790,6 +830,8 @@ func flattenFunctionAppSiteConfig(input *web.SiteConfig) []interface{} {
result["http2_enabled"] = *input.HTTP20Enabled
}

result["ip_restriction"] = flattenFunctionAppIpRestriction(input.IPSecurityRestrictions)

result["min_tls_version"] = string(input.MinTLSVersion)
result["ftps_state"] = string(input.FtpsState)

Expand Down Expand Up @@ -819,6 +861,39 @@ func expandFunctionAppConnectionStrings(d *schema.ResourceData) map[string]*web.
return output
}

func expandFunctionAppIpRestriction(input interface{}) ([]web.IPSecurityRestriction, error) {
ipSecurityRestrictions := input.([]interface{})
restrictions := make([]web.IPSecurityRestriction, 0)

for i, ipSecurityRestriction := range ipSecurityRestrictions {
restriction := ipSecurityRestriction.(map[string]interface{})

ipAddress := restriction["ip_address"].(string)
vNetSubnetID := restriction["subnet_id"].(string)

if vNetSubnetID != "" && ipAddress != "" {
return nil, fmt.Errorf(fmt.Sprintf("only one of `ip_address` or `subnet_id` can set for `site_config.0.ip_restriction.%d`", i))
}

if vNetSubnetID == "" && ipAddress == "" {
return nil, fmt.Errorf(fmt.Sprintf("one of `ip_address` or `subnet_id` must be set for `site_config.0.ip_restriction.%d`", i))
}

ipSecurityRestriction := web.IPSecurityRestriction{}
if ipAddress != "" {
ipSecurityRestriction.IPAddress = &ipAddress
}

if vNetSubnetID != "" {
ipSecurityRestriction.VnetSubnetResourceID = &vNetSubnetID
}

restrictions = append(restrictions, ipSecurityRestriction)
}

return restrictions, nil
}

func flattenFunctionAppConnectionStrings(input map[string]*web.ConnStringValueTypePair) interface{} {
results := make([]interface{}, 0)

Expand Down Expand Up @@ -870,3 +945,24 @@ func flattenFunctionAppSiteCredential(input *web.UserProperties) []interface{} {

return append(results, result)
}

func flattenFunctionAppIpRestriction(input *[]web.IPSecurityRestriction) []interface{} {
restrictions := make([]interface{}, 0)

if input == nil {
return restrictions
}

for _, v := range *input {
block := make(map[string]interface{})
if ip := v.IPAddress; ip != nil {
block["ip_address"] = *ip
}
tombuildsstuff marked this conversation as resolved.
Show resolved Hide resolved
if vNetSubnetID := v.VnetSubnetResourceID; vNetSubnetID != nil {
block["subnet_id"] = *vNetSubnetID
tombuildsstuff marked this conversation as resolved.
Show resolved Hide resolved
}
restrictions = append(restrictions, block)
}

return restrictions
}
Loading