Skip to content

Commit

Permalink
New Data Source: 'azurerm_function_app' (#5642)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brunhil authored Feb 7, 2020
1 parent a0442f0 commit d74deed
Show file tree
Hide file tree
Showing 5 changed files with 373 additions and 0 deletions.
187 changes: 187 additions & 0 deletions azurerm/internal/services/web/data_source_function_app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package web

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"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 dataSourceArmFunctionApp() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmFunctionAppRead,

Timeouts: &schema.ResourceTimeout{
Read: schema.DefaultTimeout(5 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAppServiceName,
},

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"location": azure.SchemaLocationForDataSource(),

"app_service_plan_id": {
Type: schema.TypeString,
Computed: true,
},

"app_settings": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},

"connection_string": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"value": {
Type: schema.TypeString,
Sensitive: true,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"default_hostname": {
Type: schema.TypeString,
Computed: true,
},

"enabled": {
Type: schema.TypeBool,
Computed: true,
},

"site_credential": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"username": {
Type: schema.TypeString,
Computed: true,
},
"password": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
},
},
},

"outbound_ip_addresses": {
Type: schema.TypeString,
Computed: true,
},

"possible_outbound_ip_addresses": {
Type: schema.TypeString,
Computed: true,
},

"tags": tags.Schema(),
},
}
}

func dataSourceArmFunctionAppRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Web.AppServicesClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

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

resp, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: AzureRM Function App %q (Resource Group %q) was not found", name, resourceGroup)
}
return fmt.Errorf("Error making Read request on AzureRM Function App %q: %+v", name, err)
}

appSettingsResp, err := client.ListApplicationSettings(ctx, resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(appSettingsResp.Response) {
return fmt.Errorf("Error: AzureRM Function App AppSettings %q (Resource Group %q) was not found", name, resourceGroup)
}
return fmt.Errorf("Error making Read request on AzureRM Function App AppSettings %q: %+v", name, err)
}

connectionStringsResp, err := client.ListConnectionStrings(ctx, resourceGroup, name)
if err != nil {
return fmt.Errorf("Error making Read request on AzureRM Function App ConnectionStrings %q: %+v", name, err)
}

siteCredFuture, err := client.ListPublishingCredentials(ctx, resourceGroup, name)
if err != nil {
return err
}
err = siteCredFuture.WaitForCompletionRef(ctx, client.Client)
if err != nil {
return err
}
siteCredResp, err := siteCredFuture.Result(*client)
if err != nil {
return fmt.Errorf("Error making Read request on AzureRM App Service Site Credential %q: %+v", name, err)
}

d.SetId(*resp.ID)

d.Set("name", name)
d.Set("resource_group_name", resourceGroup)

if location := resp.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}

if props := resp.SiteProperties; props != nil {
d.Set("app_service_plan_id", props.ServerFarmID)
d.Set("enabled", props.Enabled)
d.Set("default_hostname", props.DefaultHostName)
d.Set("outbound_ip_addresses", props.OutboundIPAddresses)
d.Set("possible_outbound_ip_addresses", props.PossibleOutboundIPAddresses)
}

appSettings := flattenAppServiceAppSettings(appSettingsResp.Properties)

if err = d.Set("app_settings", appSettings); err != nil {
return err
}

if err = d.Set("connection_string", flattenFunctionAppConnectionStrings(connectionStringsResp.Properties)); err != nil {
return err
}

siteCred := flattenFunctionAppSiteCredential(siteCredResp.UserProperties)
if err = d.Set("site_credential", siteCred); err != nil {
return err
}

return tags.FlattenAndSet(d, resp.Tags)
}
1 change: 1 addition & 0 deletions azurerm/internal/services/web/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
"azurerm_app_service_certificate": dataSourceAppServiceCertificate(),
"azurerm_app_service": dataSourceArmAppService(),
"azurerm_app_service_certificate_order": dataSourceArmAppServiceCertificateOrder(),
"azurerm_function_app": dataSourceArmFunctionApp(),
}
}

Expand Down
107 changes: 107 additions & 0 deletions azurerm/internal/services/web/tests/data_source_function_app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package tests

import (
"fmt"
"testing"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

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

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMFunctionAppDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMFunctionApp_basic(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMFunctionAppExists(data.ResourceName),
testCheckAzureRMFunctionAppHasNoContentShare(data.ResourceName),
resource.TestCheckResourceAttrSet(data.ResourceName, "outbound_ip_addresses"),
resource.TestCheckResourceAttrSet(data.ResourceName, "possible_outbound_ip_addresses"),
),
},
},
})
}

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

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMFunctionAppDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMFunctionApp_appSettings(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMFunctionAppExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "app_settings.hello", "world"),
),
},
},
})
}

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

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMFunctionAppDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMFunctionApp_connectionStrings(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMFunctionAppExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "connection_string.0.name", "Example"),
resource.TestCheckResourceAttr(data.ResourceName, "connection_string.0.value", "some-postgresql-connection-string"),
resource.TestCheckResourceAttr(data.ResourceName, "connection_string.0.type", "PostgreSQL"),
),
},
},
})
}

func testAccDataSourceAzureRMFunctionApp_basic(data acceptance.TestData) string {
template := testAccAzureRMFunctionApp_basic(data)
return fmt.Sprintf(`
%s
data "azurerm_function_app" "test" {
name = "${azurerm_function_app.test.name}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
`, template)
}

func testAccDataSourceAzureRMFunctionApp_connectionStrings(data acceptance.TestData) string {
template := testAccAzureRMFunctionApp_connectionStrings(data)
return fmt.Sprintf(`
%s
data "azurerm_function_app" "test" {
name = "${azurerm_function_app.test.name}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
`, template)
}

func testAccDataSourceAzureRMFunctionApp_appSettings(data acceptance.TestData) string {
template := testAccAzureRMFunctionApp_appSettings(data)
return fmt.Sprintf(`
%s
data "azurerm_function_app" "test" {
name = "${azurerm_function_app.test.name}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
`, template)
}
4 changes: 4 additions & 0 deletions website/azurerm.erb
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@
<a href="/docs/providers/azurerm/d/firewall.html">azurerm_firewall</a>
</li>

<li>
<a href="/docs/providers/azurerm/d/function_app.html">azurerm_function_app</a>
</li>

<li>
<a href="/docs/providers/azurerm/d/hdinsight_cluster.html">azurerm_hdinsight_cluster</a>
</li>
Expand Down
74 changes: 74 additions & 0 deletions website/docs/d/function_app.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
subcategory: "App Service (Web Apps)"
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_function_app"
description: |-
Gets information about an existing Function App.
---

# Data Source: azurerm_function_app

Use this data source to access information about a Function App.

## Example Usage

```hcl
data "azurerm_function_app" "example" {
name = "test-azure-functions"
resource_group_name = "${azurerm_resource_group.example.name}"
}
```

## Argument Reference

The following arguments are supported:

* `name` - The name of the Function App resource.

* `resource_group_name` - The name of the Resource Group where the Function App exists.

## Attributes Reference

The following attributes are exported:

* `id` - The ID of the Function App

* `app_service_plan_id` - The ID of the App Service Plan within which to create this Function App.

* `app_settings` - A key-value pair of App Settings.

* `connection_string` - An `connection_string` block as defined below.

* `default_hostname` - The default hostname associated with the Function App.

* `enabled` - Is the Function App enabled?

* `site_credential` - A `site_credential` block as defined below, which contains the site-level credentials used to publish to this App Service.

* `outbound_ip_addresses` - A comma separated list of outbound IP addresses.

* `possible_outbound_ip_addresses` - A comma separated list of outbound IP addresses, not all of which are necessarily in use. Superset of `outbound_ip_addresses`.

---

The `connection_string` supports the following:

* `name` - The name of the Connection String.
* `type` - The type of the Connection String.
* `value` - The value for the Connection String.

---

The `site_credential` block exports the following:

* `username` - The username which can be used to publish to this App Service
* `password` - The password associated with the username, which can be used to publish to this App Service.

### Timeouts

~> **Note:** Custom Timeouts are available [as an opt-in Beta in version 1.43 of the Azure Provider](/docs/providers/azurerm/guides/2.0-beta.html) and will be enabled by default in version 2.0 of the Azure Provider.

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:

* `read` - (Defaults to 5 minutes) Used when retrieving the Function App.

0 comments on commit d74deed

Please sign in to comment.