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

New Data Source: 'azurerm_function_app' #5642

Merged
merged 4 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.