Skip to content

Commit 3078e53

Browse files
authored
Merge branch 'master' into docs_iam_api_key_secret_key
2 parents b94662f + 3f5b763 commit 3078e53

21 files changed

+4757
-4180
lines changed

GNUmakefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ test-compile:
5353
website:
5454
@echo "Use this site to preview markdown rendering: https://registry.terraform.io/tools/doc-preview"
5555

56-
.PHONY: build test testacc vet fmt fmtcheck errcheck test-compile website
56+
.PHONY: build test testacc vet fmt fmtcheck errcheck test-compile website docs
5757

5858
tfproviderlint:
5959
go tool tfproviderlint -R014=false -AT001.ignored-filename-suffixes=_data_source_test.go ./...
@@ -63,3 +63,8 @@ tfproviderdocs:
6363

6464
tfproviderlintx:
6565
go tool tfproviderlintx -XR001=false -XS002=false ./...
66+
67+
docs:
68+
go tool tfplugindocs validate
69+
rm -fr ./docs
70+
go tool tfplugindocs generate

docs/resources/key_manager_key.md

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,80 @@ This resource allows you to create and manage cryptographic keys in Scaleway Key
99

1010
## Example Usage
1111

12+
### Symmetric Encryption Key
13+
1214
```terraform
13-
resource "scaleway_key_manager_key" "main" {
14-
name = "my-kms-key"
15-
region = "fr-par"
16-
project_id = "your-project-id" # optional, will use provider default if omitted
17-
usage = "symmetric_encryption"
18-
description = "Key for encrypting secrets"
19-
tags = ["env:prod", "kms"]
20-
unprotected = true
15+
resource "scaleway_key_manager_key" "symmetric" {
16+
name = "my-kms-key"
17+
region = "fr-par"
18+
project_id = "your-project-id" # optional, will use provider default if omitted
19+
usage = "symmetric_encryption"
20+
algorithm = "aes_256_gcm"
21+
description = "Key for encrypting secrets"
22+
tags = ["env:prod", "kms"]
23+
unprotected = true
2124
2225
rotation_policy {
2326
rotation_period = "720h" # 30 days
2427
}
2528
}
2629
```
2730

31+
### Asymmetric Encryption Key with RSA-4096
32+
33+
```terraform
34+
resource "scaleway_key_manager_key" "rsa_4096" {
35+
name = "rsa-4096-key"
36+
region = "fr-par"
37+
usage = "asymmetric_encryption"
38+
algorithm = "rsa_oaep_4096_sha256"
39+
description = "Key for encrypting large files with RSA-4096"
40+
unprotected = true
41+
}
42+
```
43+
44+
### Asymmetric Signing Key
45+
46+
```terraform
47+
resource "scaleway_key_manager_key" "signing" {
48+
name = "signing-key"
49+
region = "fr-par"
50+
usage = "asymmetric_signing"
51+
algorithm = "rsa_pss_2048_sha256"
52+
description = "Key for signing documents"
53+
unprotected = true
54+
}
55+
```
56+
2857
## Argument Reference
2958

3059
The following arguments are supported:
3160

3261
- `name` (String) – The name of the key.
3362
- `region` (String) – The region in which to create the key (e.g., `fr-par`).
34-
- `project_id` (String, Optional) – The ID of the project the key belongs to.
35-
- `usage` (String, **Required**) – The usage of the key. Valid values are:
36-
- `symmetric_encryption`
37-
- `asymmetric_encryption`
38-
- `asymmetric_signing`
63+
- `project_id` (String, Optional) – The ID of the project the key belongs to.
64+
65+
**Key Usage and Algorithm (both required):**
66+
67+
- `usage` (String, Required) – The usage type of the key. Valid values:
68+
- `symmetric_encryption` – For symmetric encryption operations
69+
- `asymmetric_encryption` – For asymmetric encryption operations
70+
- `asymmetric_signing` – For digital signing operations
71+
72+
- `algorithm` (String, Required) – The cryptographic algorithm to use. Valid values depend on the `usage`:
73+
- For `symmetric_encryption`:
74+
- `aes_256_gcm`
75+
- For `asymmetric_encryption`:
76+
- `rsa_oaep_2048_sha256`
77+
- `rsa_oaep_3072_sha256`
78+
- `rsa_oaep_4096_sha256`
79+
- For `asymmetric_signing`:
80+
- `ec_p256_sha256`
81+
- `rsa_pss_2048_sha256`
82+
- `rsa_pkcs1_2048_sha256`
83+
84+
**Other arguments:**
85+
3986
- `description` (String, Optional) – A description for the key.
4087
- `tags` (List of String, Optional) – A list of tags to assign to the key.
4188
- `unprotected` (Boolean, Optional) – If `true`, the key can be deleted. Defaults to `false` (protected).
@@ -57,8 +104,6 @@ In addition to all arguments above, the following attributes are exported:
57104
- `protected` – Whether the key is protected from deletion.
58105
- `locked` – Whether the key is locked.
59106
- `rotated_at` – The date and time when the key was last rotated.
60-
- `origin_read` – The origin of the key as returned by the API.
61-
- `region_read` – The region of the key as returned by the API.
62107
- `rotation_policy` (Block)
63108
- `rotation_period` – The period between key rotations.
64109
- `next_rotation_at` – The date and time of the next scheduled rotation.
@@ -77,15 +122,5 @@ terraform import scaleway_key_manager_key.main fr-par/11111111-2222-3333-4444-55
77122
- **Rotation Policy**: The `rotation_policy` block allows you to set automatic rotation for your key.
78123
- **Origin**: The `origin` argument is optional and defaults to `scaleway_kms`. Use `external` if you want to import an external key (see Scaleway documentation for details).
79124
- **Project and Region**: If not specified, `project_id` and `region` will default to the provider configuration.
125+
- **Algorithm Validation**: The provider validates that the specified `algorithm` is compatible with the `usage` type at plan time, providing early feedback on configuration errors.
80126

81-
## Example: Asymmetric Key
82-
83-
```terraform
84-
resource "scaleway_key_manager_key" "asym" {
85-
name = "asymmetric-key"
86-
region = "fr-par"
87-
usage = "asymmetric_signing"
88-
description = "Key for signing documents"
89-
unprotected = true
90-
}
91-
```

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
github.com/nats-io/jwt/v2 v2.8.0
3131
github.com/nats-io/nats.go v1.46.1
3232
github.com/robfig/cron/v3 v3.0.1
33-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35.0.20250929150437-c65b49480cff
33+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35.0.20251015050748-12aafea99911
3434
github.com/stretchr/testify v1.11.1
3535
golang.org/x/crypto v0.43.0
3636
golang.org/x/sync v0.17.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
457457
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
458458
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
459459
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
460-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35.0.20250929150437-c65b49480cff h1:1XC8rVPK4hr2lHdHajSurEV2Orp8eMGQ42vqh4hVX7M=
461-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35.0.20250929150437-c65b49480cff/go.mod h1:DVB9HV7nK7TdTRqlpdxw6T0Wxg+aB9xPBEpO3aM2iqQ=
460+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35.0.20251015050748-12aafea99911 h1:puwRtGGoGw9Rw3qlB7ltimV2+uugkalN08DyVEL1VoE=
461+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35.0.20251015050748-12aafea99911/go.mod h1:SVm1Zk6UpZtqZN6KtEQpjC+v+Lir4tyVfhQTU19q3PA=
462462
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
463463
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
464464
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=

templates/template_test.go renamed to internal/docs/template_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package template_test
1+
package docs_test
22

33
import (
44
"bufio"
@@ -13,23 +13,30 @@ import (
1313
var gotypeRE = regexp.MustCompile(`\{\{.*gotype:.*}}`)
1414

1515
func TestGoTypeDefined(t *testing.T) {
16-
err := filepath.WalkDir("resources", func(path string, _ fs.DirEntry, _ error) error {
16+
err := filepath.WalkDir("../../templates/resources", func(path string, _ fs.DirEntry, _ error) error {
1717
if isTemplate := strings.Contains(path, "tmpl"); isTemplate {
1818
f, err := os.Open(path)
1919
if err != nil {
2020
t.Fatalf("cannot open %s", path)
2121
}
22-
defer f.Close()
22+
defer func(f *os.File) {
23+
err := f.Close()
24+
if err != nil {
25+
t.Fatal(err.Error())
26+
}
27+
}(f)
2328

2429
scanner := bufio.NewScanner(f)
2530
if !scanner.Scan() {
2631
t.Logf("❌ %s: file is empty", path)
2732
t.Fail()
2833
}
34+
2935
firstLine := scanner.Text()
3036
if gotypeRE.MatchString(firstLine) {
3137
return nil
3238
}
39+
3340
t.Logf("gotype missing at top of file: %s", path)
3441
t.Fail()
3542
}

internal/services/keymanager/helpers.go

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@ import (
1313
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
1414
)
1515

16+
const (
17+
usageSymmetricEncryption = "symmetric_encryption"
18+
usageAsymmetricEncryption = "asymmetric_encryption"
19+
usageAsymmetricSigning = "asymmetric_signing"
20+
)
21+
1622
func UsageToString(u *key_manager.KeyUsage) string {
1723
if u == nil {
1824
return ""
1925
}
2026

2127
if u.SymmetricEncryption != nil {
22-
return "symmetric_encryption"
28+
return usageSymmetricEncryption
2329
}
2430

2531
if u.AsymmetricEncryption != nil {
26-
return "asymmetric_encryption"
32+
return usageAsymmetricEncryption
2733
}
2834

2935
if u.AsymmetricSigning != nil {
30-
return "asymmetric_signing"
36+
return usageAsymmetricSigning
3137
}
3238

3339
return ""
@@ -55,17 +61,43 @@ func NewKeyManagerAPIWithRegionAndID(m any, id string) (*key_manager.API, scw.Re
5561
return client, region, keyID, nil
5662
}
5763

58-
func ExpandKeyUsage(usage string) *key_manager.KeyUsage {
64+
func ExpandKeyUsageFromFields(d *schema.ResourceData) *key_manager.KeyUsage {
65+
if v, ok := d.GetOk("usage_symmetric_encryption"); ok {
66+
alg := key_manager.KeyAlgorithmSymmetricEncryption(v.(string))
67+
68+
return &key_manager.KeyUsage{SymmetricEncryption: &alg}
69+
}
70+
71+
if v, ok := d.GetOk("usage_asymmetric_encryption"); ok {
72+
alg := key_manager.KeyAlgorithmAsymmetricEncryption(v.(string))
73+
74+
return &key_manager.KeyUsage{AsymmetricEncryption: &alg}
75+
}
76+
77+
if v, ok := d.GetOk("usage_asymmetric_signing"); ok {
78+
alg := key_manager.KeyAlgorithmAsymmetricSigning(v.(string))
79+
80+
return &key_manager.KeyUsage{AsymmetricSigning: &alg}
81+
}
82+
83+
if v, ok := d.GetOk("usage"); ok {
84+
return ExpandKeyUsageLegacy(v.(string))
85+
}
86+
87+
return nil
88+
}
89+
90+
func ExpandKeyUsageLegacy(usage string) *key_manager.KeyUsage {
5991
switch usage {
60-
case "symmetric_encryption":
92+
case usageSymmetricEncryption:
6193
alg := key_manager.KeyAlgorithmSymmetricEncryptionAes256Gcm
6294

6395
return &key_manager.KeyUsage{SymmetricEncryption: &alg}
64-
case "asymmetric_encryption":
96+
case usageAsymmetricEncryption:
6597
alg := key_manager.KeyAlgorithmAsymmetricEncryptionRsaOaep3072Sha256
6698

6799
return &key_manager.KeyUsage{AsymmetricEncryption: &alg}
68-
case "asymmetric_signing":
100+
case usageAsymmetricSigning:
69101
alg := key_manager.KeyAlgorithmAsymmetricSigningEcP256Sha256
70102

71103
return &key_manager.KeyUsage{AsymmetricSigning: &alg}
@@ -74,6 +106,26 @@ func ExpandKeyUsage(usage string) *key_manager.KeyUsage {
74106
}
75107
}
76108

109+
func AlgorithmFromKeyUsage(u *key_manager.KeyUsage) string {
110+
if u == nil {
111+
return ""
112+
}
113+
114+
if u.SymmetricEncryption != nil {
115+
return string(*u.SymmetricEncryption)
116+
}
117+
118+
if u.AsymmetricEncryption != nil {
119+
return string(*u.AsymmetricEncryption)
120+
}
121+
122+
if u.AsymmetricSigning != nil {
123+
return string(*u.AsymmetricSigning)
124+
}
125+
126+
return ""
127+
}
128+
77129
func ExpandKeyRotationPolicy(v any) (*key_manager.KeyRotationPolicy, error) {
78130
list, ok := v.([]any)
79131
if !ok || len(list) == 0 {
@@ -99,7 +151,6 @@ func ExpandKeyRotationPolicy(v any) (*key_manager.KeyRotationPolicy, error) {
99151
RotationPeriod: scw.NewDurationFromTimeDuration(period),
100152
}
101153

102-
// Handle next_rotation_at if provided
103154
if nextRotationStr, ok := m["next_rotation_at"].(string); ok && nextRotationStr != "" {
104155
nextRotation, err := time.Parse(time.RFC3339, nextRotationStr)
105156
if err != nil {

0 commit comments

Comments
 (0)