Skip to content

Commit b7ed122

Browse files
apps: Add support for global env vars (Fixes: #549). (#550)
1 parent 962d2d6 commit b7ed122

4 files changed

Lines changed: 100 additions & 14 deletions

File tree

digitalocean/app_spec.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ func appSpecSchema() map[string]*schema.Schema {
4747
Optional: true,
4848
Elem: appSpecDatabaseSchema(),
4949
},
50+
"env": {
51+
Type: schema.TypeSet,
52+
Optional: true,
53+
Elem: appSpecEnvSchema(),
54+
Set: schema.HashResource(appSpecEnvSchema()),
55+
},
5056
}
5157
}
5258

@@ -421,6 +427,7 @@ func expandAppSpec(config []interface{}) *godo.AppSpec {
421427
StaticSites: expandAppSpecStaticSites(appSpecConfig["static_site"].([]interface{})),
422428
Workers: expandAppSpecWorkers(appSpecConfig["worker"].([]interface{})),
423429
Databases: expandAppSpecDatabases(appSpecConfig["database"].([]interface{})),
430+
Envs: expandAppEnvs(appSpecConfig["env"].(*schema.Set).List()),
424431
}
425432

426433
return appSpec
@@ -452,6 +459,10 @@ func flattenAppSpec(spec *godo.AppSpec) []map[string]interface{} {
452459
r["database"] = flattenAppSpecDatabases((*spec).Databases)
453460
}
454461

462+
if len((*spec).Envs) > 0 {
463+
r["env"] = flattenAppEnvs((*spec).Envs)
464+
}
465+
455466
result = append(result, r)
456467
}
457468

digitalocean/resource_digitalocean_app_test.go

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,27 +161,56 @@ func TestAccDigitalOceanApp_Envs(t *testing.T) {
161161

162162
oneEnv := `
163163
env {
164-
key = "FOO"
164+
key = "COMPONENT_FOO"
165165
value = "bar"
166166
}
167167
`
168168

169169
twoEnvs := `
170170
env {
171-
key = "FOO"
171+
key = "COMPONENT_FOO"
172172
value = "bar"
173173
}
174174
175175
env {
176-
key = "FIZZ"
176+
key = "COMPONENT_FIZZ"
177177
value = "pop"
178178
scope = "BUILD_TIME"
179179
}
180180
`
181181

182182
oneEnvUpdated := `
183183
env {
184-
key = "FOO"
184+
key = "COMPONENT_FOO"
185+
value = "baz"
186+
scope = "RUN_TIME"
187+
type = "GENERAL"
188+
}
189+
`
190+
191+
oneAppEnv := `
192+
env {
193+
key = "APP_FOO"
194+
value = "bar"
195+
}
196+
`
197+
198+
twoAppEnvs := `
199+
env {
200+
key = "APP_FOO"
201+
value = "bar"
202+
}
203+
204+
env {
205+
key = "APP_FIZZ"
206+
value = "pop"
207+
scope = "BUILD_TIME"
208+
}
209+
`
210+
211+
oneAppEnvUpdated := `
212+
env {
213+
key = "APP_FOO"
185214
value = "baz"
186215
scope = "RUN_TIME"
187216
type = "GENERAL"
@@ -194,7 +223,7 @@ func TestAccDigitalOceanApp_Envs(t *testing.T) {
194223
CheckDestroy: testAccCheckDigitalOceanAppDestroy,
195224
Steps: []resource.TestStep{
196225
{
197-
Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_Envs, appName, oneEnv),
226+
Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_Envs, appName, oneEnv, oneAppEnv),
198227
Check: resource.ComposeTestCheckFunc(
199228
testAccCheckDigitalOceanAppExists("digitalocean_app.foobar", &app),
200229
resource.TestCheckResourceAttr(
@@ -205,15 +234,26 @@ func TestAccDigitalOceanApp_Envs(t *testing.T) {
205234
"digitalocean_app.foobar",
206235
"spec.0.service.0.env.*",
207236
map[string]string{
208-
"key": "FOO",
237+
"key": "COMPONENT_FOO",
238+
"value": "bar",
239+
"scope": "RUN_AND_BUILD_TIME",
240+
},
241+
),
242+
resource.TestCheckResourceAttr(
243+
"digitalocean_app.foobar", "spec.0.env.#", "1"),
244+
setutil.TestCheckTypeSetElemNestedAttrs(
245+
"digitalocean_app.foobar",
246+
"spec.0.env.*",
247+
map[string]string{
248+
"key": "APP_FOO",
209249
"value": "bar",
210250
"scope": "RUN_AND_BUILD_TIME",
211251
},
212252
),
213253
),
214254
},
215255
{
216-
Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_Envs, appName, twoEnvs),
256+
Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_Envs, appName, twoEnvs, twoAppEnvs),
217257
Check: resource.ComposeTestCheckFunc(
218258
testAccCheckDigitalOceanAppExists("digitalocean_app.foobar", &app),
219259
resource.TestCheckResourceAttr(
@@ -224,7 +264,7 @@ func TestAccDigitalOceanApp_Envs(t *testing.T) {
224264
"digitalocean_app.foobar",
225265
"spec.0.service.0.env.*",
226266
map[string]string{
227-
"key": "FOO",
267+
"key": "COMPONENT_FOO",
228268
"value": "bar",
229269
"scope": "RUN_AND_BUILD_TIME",
230270
},
@@ -233,15 +273,35 @@ func TestAccDigitalOceanApp_Envs(t *testing.T) {
233273
"digitalocean_app.foobar",
234274
"spec.0.service.0.env.*",
235275
map[string]string{
236-
"key": "FIZZ",
276+
"key": "COMPONENT_FIZZ",
277+
"value": "pop",
278+
"scope": "BUILD_TIME",
279+
},
280+
),
281+
resource.TestCheckResourceAttr(
282+
"digitalocean_app.foobar", "spec.0.env.#", "2"),
283+
setutil.TestCheckTypeSetElemNestedAttrs(
284+
"digitalocean_app.foobar",
285+
"spec.0.env.*",
286+
map[string]string{
287+
"key": "APP_FOO",
288+
"value": "bar",
289+
"scope": "RUN_AND_BUILD_TIME",
290+
},
291+
),
292+
setutil.TestCheckTypeSetElemNestedAttrs(
293+
"digitalocean_app.foobar",
294+
"spec.0.env.*",
295+
map[string]string{
296+
"key": "APP_FIZZ",
237297
"value": "pop",
238298
"scope": "BUILD_TIME",
239299
},
240300
),
241301
),
242302
},
243303
{
244-
Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_Envs, appName, oneEnvUpdated),
304+
Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_Envs, appName, oneEnvUpdated, oneAppEnvUpdated),
245305
Check: resource.ComposeTestCheckFunc(
246306
testAccCheckDigitalOceanAppExists("digitalocean_app.foobar", &app),
247307
resource.TestCheckResourceAttr(
@@ -252,7 +312,18 @@ func TestAccDigitalOceanApp_Envs(t *testing.T) {
252312
"digitalocean_app.foobar",
253313
"spec.0.service.0.env.*",
254314
map[string]string{
255-
"key": "FOO",
315+
"key": "COMPONENT_FOO",
316+
"value": "baz",
317+
"scope": "RUN_TIME",
318+
},
319+
),
320+
resource.TestCheckResourceAttr(
321+
"digitalocean_app.foobar", "spec.0.env.#", "1"),
322+
setutil.TestCheckTypeSetElemNestedAttrs(
323+
"digitalocean_app.foobar",
324+
"spec.0.env.*",
325+
map[string]string{
326+
"key": "APP_FOO",
256327
"value": "baz",
257328
"scope": "RUN_TIME",
258329
},
@@ -487,6 +558,8 @@ resource "digitalocean_app" "foobar" {
487558
488559
%s
489560
}
561+
562+
%s
490563
}
491564
}`
492565

docs/resources/app.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ The following arguments are supported:
122122
- `name` - (Required) The name of the app. Must be unique across all apps in the same account.
123123
- `region` - The slug for the DigitalOcean data center region hosting the app.
124124
- `domains` - A list of hostnames where the application will be available.
125+
- `env` - Describes an app-wide environment variable made available to all components.
126+
* `key` - The name of the environment variable.
127+
* `value` - The value of the environment variable.
128+
* `scope` - The visibility scope of the environment variable. One of `RUN_TIME`, `BUILD_TIME`, or `RUN_AND_BUILD_TIME` (default).
129+
* `type` - The type of the environment variable, `GENERAL` or `SECRET`.
125130

126131
A spec can contain multiple components.
127132

go.sum

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
8989
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
9090
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
9191
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
92-
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
9392
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
9493
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
9594
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -118,7 +117,6 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
118117
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
119118
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
120119
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
121-
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
122120
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
123121
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
124122
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -237,7 +235,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
237235
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
238236
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
239237
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
240-
github.com/mitchellh/cli v1.1.1 h1:J64v/xD7Clql+JVKSvkYojLOXu1ibnY9ZjGLwSt/89w=
241238
github.com/mitchellh/cli v1.1.1/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
242239
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
243240
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=

0 commit comments

Comments
 (0)