Skip to content

Commit 6eb6148

Browse files
Codelaxremyleone
andauthored
feat(container): add secret environment variables (#1544)
Co-authored-by: Rémy Léone <[email protected]>
1 parent f1f404a commit 6eb6148

11 files changed

+2217
-862
lines changed

docs/resources/container.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ The following arguments are optional:
6060

6161
- `environment_variables` - (Optional) The [environment](https://www.scaleway.com/en/docs/compute/containers/concepts/#environment-variables) variables of the container.
6262

63+
- `secret_environment_variables` - (Optional) The [secret environment](https://www.scaleway.com/en/docs/compute/containers/concepts/#secrets) variables of the container.
64+
6365
- `min_scale` - (Optional) The minimum of running container instances continuously. Defaults to 0.
6466

6567
- `max_scale` - (Optional) The maximum of number of instances this container can scale to. Default to 20.

docs/resources/container_namespace.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ The following arguments are supported:
3636

3737
- `environment_variables` - The environment variables of the namespace.
3838

39+
- `secret_environment_variables` - The secret environment variables of the namespace.
40+
3941
- `destroy_registry` - (Defaults to false). Destroy linked container registry on deletion.
4042

4143
## Attributes Reference

scaleway/helpers_container.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,17 @@ func waitForContainer(ctx context.Context, api *container.API, containerID strin
145145

146146
return api.WaitForContainer(&request, scw.WithContext(ctx))
147147
}
148+
149+
func expandContainerSecrets(secretsRawMap interface{}) []*container.Secret {
150+
secretsMap := secretsRawMap.(map[string]interface{})
151+
secrets := make([]*container.Secret, 0, len(secretsMap))
152+
153+
for k, v := range secretsMap {
154+
secrets = append(secrets, &container.Secret{
155+
Key: k,
156+
Value: expandStringPtr(v),
157+
})
158+
}
159+
160+
return secrets
161+
}

scaleway/resource_container.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ func resourceScalewayContainer() *schema.Resource {
6060
},
6161
ValidateDiagFunc: validation.MapKeyLenBetween(0, 100),
6262
},
63+
"secret_environment_variables": {
64+
Type: schema.TypeMap,
65+
Optional: true,
66+
Sensitive: true,
67+
Description: "The secret environment variables to be injected into your container at runtime.",
68+
Elem: &schema.Schema{
69+
Type: schema.TypeString,
70+
ValidateFunc: validation.StringLenBetween(0, 1000),
71+
},
72+
ValidateDiagFunc: validation.MapKeyLenBetween(0, 100),
73+
},
6374
"min_scale": {
6475
Type: schema.TypeInt,
6576
Computed: true,
@@ -292,6 +303,10 @@ func resourceScalewayContainerUpdate(ctx context.Context, d *schema.ResourceData
292303
req.EnvironmentVariables = expandMapPtrStringString(envVariablesRaw)
293304
}
294305

306+
if d.HasChanges("secret_environment_variables") {
307+
req.SecretEnvironmentVariables = expandContainerSecrets(d.Get("secret_environment_variables"))
308+
}
309+
295310
if d.HasChanges("min_scale") {
296311
req.MinScale = scw.Uint32Ptr(uint32(d.Get("min_scale").(int)))
297312
}

scaleway/resource_container_namespace.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ func resourceScalewayContainerNamespace() *schema.Resource {
5151
},
5252
ValidateDiagFunc: validation.MapKeyLenBetween(0, 100),
5353
},
54+
"secret_environment_variables": {
55+
Type: schema.TypeMap,
56+
Optional: true,
57+
Sensitive: true,
58+
Description: "The secret environment variables of the container namespace",
59+
Elem: &schema.Schema{
60+
Type: schema.TypeString,
61+
ValidateFunc: validation.StringLenBetween(0, 1000),
62+
},
63+
ValidateDiagFunc: validation.MapKeyLenBetween(0, 100),
64+
},
5465
"registry_endpoint": {
5566
Type: schema.TypeString,
5667
Computed: true,
@@ -81,11 +92,12 @@ func resourceScalewayContainerNamespaceCreate(ctx context.Context, d *schema.Res
8192
}
8293

8394
ns, err := api.CreateNamespace(&container.CreateNamespaceRequest{
84-
Description: expandStringPtr(d.Get("description").(string)),
85-
EnvironmentVariables: expandMapPtrStringString(d.Get("environment_variables")),
86-
Name: expandOrGenerateString(d.Get("name").(string), "ns"),
87-
ProjectID: d.Get("project_id").(string),
88-
Region: region,
95+
Description: expandStringPtr(d.Get("description").(string)),
96+
EnvironmentVariables: expandMapPtrStringString(d.Get("environment_variables")),
97+
SecretEnvironmentVariables: expandContainerSecrets(d.Get("secret_environment_variables")),
98+
Name: expandOrGenerateString(d.Get("name").(string), "ns"),
99+
ProjectID: d.Get("project_id").(string),
100+
Region: region,
89101
}, scw.WithContext(ctx))
90102
if err != nil {
91103
return diag.FromErr(err)
@@ -152,6 +164,10 @@ func resourceScalewayContainerNamespaceUpdate(ctx context.Context, d *schema.Res
152164
req.EnvironmentVariables = expandMapPtrStringString(d.Get("environment_variables"))
153165
}
154166

167+
if d.HasChange("secret_environment_variables") {
168+
req.SecretEnvironmentVariables = expandContainerSecrets(d.Get("secret_environment_variables"))
169+
}
170+
155171
if _, err := api.UpdateNamespace(req, scw.WithContext(ctx)); err != nil {
156172
return diag.FromErr(err)
157173
}

scaleway/resource_container_namespace_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,17 @@ func TestAccScalewayContainerNamespace_Basic(t *testing.T) {
8888
environment_variables = {
8989
"test" = "test"
9090
}
91+
secret_environment_variables = {
92+
"test_secret" = "test_secret"
93+
}
9194
}
9295
`,
9396
Check: resource.ComposeTestCheckFunc(
9497
testAccCheckScalewayContainerNamespaceExists(tt, "scaleway_container_namespace.main"),
9598
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "description", ""),
9699
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "name", "test-cr-ns-01"),
97100
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "environment_variables.test", "test"),
101+
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "secret_environment_variables.test_secret", "test_secret"),
98102

99103
testCheckResourceAttrUUID("scaleway_container_namespace.main", "id"),
100104
),
@@ -118,12 +122,16 @@ func TestAccScalewayContainerNamespace_Basic(t *testing.T) {
118122
environment_variables = {
119123
"test" = "test"
120124
}
125+
secret_environment_variables = {
126+
"test_secret" = "test_secret"
127+
}
121128
}
122129
`,
123130
Check: resource.ComposeTestCheckFunc(
124131
testAccCheckScalewayContainerNamespaceExists(tt, "scaleway_container_namespace.main"),
125132
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "name", "tf-env-test"),
126133
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "environment_variables.test", "test"),
134+
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "secret_environment_variables.test_secret", "test_secret"),
127135

128136
testCheckResourceAttrUUID("scaleway_container_namespace.main", "id"),
129137
),
@@ -135,12 +143,16 @@ func TestAccScalewayContainerNamespace_Basic(t *testing.T) {
135143
environment_variables = {
136144
"foo" = "bar"
137145
}
146+
secret_environment_variables = {
147+
"foo_secret" = "bar_secret"
148+
}
138149
}
139150
`,
140151
Check: resource.ComposeTestCheckFunc(
141152
testAccCheckScalewayContainerNamespaceExists(tt, "scaleway_container_namespace.main"),
142153
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "name", "tf-env-test"),
143154
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "environment_variables.foo", "bar"),
155+
resource.TestCheckResourceAttr("scaleway_container_namespace.main", "secret_environment_variables.foo_secret", "bar_secret"),
144156

145157
testCheckResourceAttrUUID("scaleway_container_namespace.main", "id"),
146158
),

scaleway/resource_container_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,85 @@ func TestAccScalewayContainer_Basic(t *testing.T) {
171171
})
172172
}
173173

174+
func TestAccScalewayContainer_Env(t *testing.T) {
175+
tt := NewTestTools(t)
176+
defer tt.Cleanup()
177+
resource.ParallelTest(t, resource.TestCase{
178+
PreCheck: func() { testAccPreCheck(t) },
179+
ProviderFactories: tt.ProviderFactories,
180+
CheckDestroy: testAccCheckScalewayContainerDestroy(tt),
181+
Steps: []resource.TestStep{
182+
{
183+
Config: `
184+
resource scaleway_container_namespace main {
185+
}
186+
187+
resource scaleway_container main {
188+
namespace_id = scaleway_container_namespace.main.id
189+
environment_variables = {
190+
"test" = "test"
191+
}
192+
secret_environment_variables = {
193+
"test_secret" = "test_secret"
194+
}
195+
}
196+
`,
197+
Check: resource.ComposeTestCheckFunc(
198+
testAccCheckScalewayContainerExists(tt, "scaleway_container.main"),
199+
testCheckResourceAttrUUID("scaleway_container_namespace.main", "id"),
200+
testCheckResourceAttrUUID("scaleway_container.main", "id"),
201+
resource.TestCheckResourceAttr("scaleway_container.main", "environment_variables.test", "test"),
202+
resource.TestCheckResourceAttr("scaleway_container.main", "secret_environment_variables.test_secret", "test_secret"),
203+
),
204+
},
205+
{
206+
Config: `
207+
resource scaleway_container_namespace main {
208+
}
209+
210+
resource scaleway_container main {
211+
namespace_id = scaleway_container_namespace.main.id
212+
environment_variables = {
213+
"foo" = "bar"
214+
}
215+
secret_environment_variables = {
216+
"foo_secret" = "bar_secret"
217+
}
218+
}
219+
`,
220+
Check: resource.ComposeTestCheckFunc(
221+
testAccCheckScalewayContainerExists(tt, "scaleway_container.main"),
222+
testCheckResourceAttrUUID("scaleway_container_namespace.main", "id"),
223+
testCheckResourceAttrUUID("scaleway_container.main", "id"),
224+
resource.TestCheckResourceAttr("scaleway_container.main", "environment_variables.foo", "bar"),
225+
resource.TestCheckResourceAttr("scaleway_container.main", "secret_environment_variables.foo_secret", "bar_secret"),
226+
),
227+
},
228+
{
229+
Config: `
230+
resource scaleway_container_namespace main {
231+
}
232+
233+
resource scaleway_container main {
234+
namespace_id = scaleway_container_namespace.main.id
235+
environment_variables = {}
236+
secret_environment_variables = {}
237+
}
238+
`,
239+
Check: resource.ComposeTestCheckFunc(
240+
testAccCheckScalewayContainerExists(tt, "scaleway_container.main"),
241+
testCheckResourceAttrUUID("scaleway_container_namespace.main", "id"),
242+
testCheckResourceAttrUUID("scaleway_container.main", "id"),
243+
resource.TestCheckNoResourceAttr("scaleway_container.main", "environment_variables.%"),
244+
resource.TestCheckNoResourceAttr("scaleway_container.main", "secret_environment_variables.%"),
245+
resource.TestCheckNoResourceAttr("scaleway_container.main", "environment_variables.foo"),
246+
resource.TestCheckNoResourceAttr("scaleway_container.main", "secret_environment_variables.foo_secret"),
247+
),
248+
},
249+
},
250+
})
251+
}
252+
174253
func TestAccScalewayContainer_WithIMG(t *testing.T) {
175254
if !*UpdateCassettes {
176255
t.Skip("Skipping Container test with image as this kind of test can't dump docker pushing process on cassettes")

0 commit comments

Comments
 (0)