diff --git a/digitalocean/app/app_spec.go b/digitalocean/app/app_spec.go index 68ccb1ea7..fddfdf72c 100644 --- a/digitalocean/app/app_spec.go +++ b/digitalocean/app/app_spec.go @@ -41,6 +41,12 @@ func appSpecSchema(isResource bool) map[string]*schema.Schema { Computed: true, Elem: appSpecDomainSchema(), }, + "features": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: "List of features which is applied to the app", + }, "domains": { Type: schema.TypeSet, Optional: true, @@ -1003,6 +1009,7 @@ func expandAppSpec(config []interface{}) *godo.AppSpec { appSpec := &godo.AppSpec{ Name: appSpecConfig["name"].(string), Region: appSpecConfig["region"].(string), + Features: expandAppSpecFeatures(appSpecConfig["features"].(*schema.Set)), Services: expandAppSpecServices(appSpecConfig["service"].([]interface{})), StaticSites: expandAppSpecStaticSites(appSpecConfig["static_site"].([]interface{})), Workers: expandAppSpecWorkers(appSpecConfig["worker"].([]interface{})), @@ -1033,6 +1040,7 @@ func flattenAppSpec(d *schema.ResourceData, spec *godo.AppSpec) []map[string]int r := make(map[string]interface{}) r["name"] = (*spec).Name r["region"] = (*spec).Region + r["features"] = (*spec).Features if len((*spec).Domains) > 0 { r["domains"] = flattenAppDomainSpec((*spec).Domains) @@ -1712,6 +1720,18 @@ func flattenAppSpecStaticSites(sites []*godo.AppStaticSiteSpec) []map[string]int return result } +func expandAppSpecFeatures(featuresConfig *schema.Set) []string { + features := []string{} + + for _, feature := range featuresConfig.List() { + if featureString, ok := feature.(string); ok { + features = append(features, featureString) + } + } + + return features +} + func expandAppSpecWorkers(config []interface{}) []*godo.AppWorkerSpec { appWorkers := make([]*godo.AppWorkerSpec, 0, len(config)) diff --git a/digitalocean/app/resource_app_test.go b/digitalocean/app/resource_app_test.go index a901782e2..e395e88e3 100644 --- a/digitalocean/app/resource_app_test.go +++ b/digitalocean/app/resource_app_test.go @@ -853,6 +853,27 @@ func testAccCheckDigitalOceanAppExists(n string, app *godo.App) resource.TestChe } } +func TestAccDigitalOceanApp_Features(t *testing.T) { + var app godo.App + appName := acceptance.RandomTestName() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.TestAccPreCheck(t) }, + Providers: acceptance.TestAccProviders, + CheckDestroy: testAccCheckDigitalOceanAppDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_withFeatures, appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanAppExists("digitalocean_app.foobar", &app), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.features.0", "buildpack-stack=ubuntu-18"), + ), + }, + }, + }) +} + var testAccCheckDigitalOceanAppConfig_basic = ` resource "digitalocean_app" "foobar" { spec { @@ -918,6 +939,25 @@ resource "digitalocean_app" "foobar" { } }` +var testAccCheckDigitalOceanAppConfig_withFeatures = ` +resource "digitalocean_app" "foobar" { + spec { + name = "%s" + region = "ams" + features = ["buildpack-stack=ubuntu-18"] + + service { + name = "go-service-with-features" + instance_size_slug = "basic-xxs" + + git { + repo_clone_url = "https://github.com/digitalocean/sample-golang.git" + branch = "main" + } + } + } +}` + var testAccCheckDigitalOceanAppConfig_addService = ` resource "digitalocean_app" "foobar" { spec { diff --git a/docs/resources/app.md b/docs/resources/app.md index 8a2a56b70..32f345114 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -158,6 +158,7 @@ The following arguments are supported: * `spec` - (Required) A DigitalOcean App spec describing the app. - `name` - (Required) The name of the app. Must be unique across all apps in the same account. - `region` - The slug for the DigitalOcean data center region hosting the app. + - `features` - A list of the features applied to the app. The default buildpack can be overridden here. List of available buildpacks can be found using the [doctl CLI](https://docs.digitalocean.com/reference/doctl/reference/apps/list-buildpacks/) - `domain` - Describes a domain where the application will be made available. * `name` - The hostname for the domain. * `type` - The domain type, which can be one of the following: