Skip to content

Commit 2fa078e

Browse files
authored
Merge pull request #18 from tickup-se/aws-secret-key-value
Decode AWS Secret manager Key/Value
2 parents 45f8b9f + fab4288 commit 2fa078e

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Summary:
3333

3434
User can put AWS secret ARN as environment variable value. The `secrets-init` will resolve any environment value, using specified ARN, to referenced secret value.
3535

36+
If the secret is saved as a Key/Value pair, all the keys are applied to as environment variables and passed. The environment variable passed is ignored unless it is inside the key/value pair.
3637
```sh
3738
# environment variable passed to `secrets-init`
3839
MY_DB_PASSWORD=arn:aws:secretsmanager:$AWS_REGION:$AWS_ACCOUNT_ID:secret:mydbpassword-cdma3

pkg/secrets/aws/secrets.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package aws
22

33
import (
44
"context"
5+
"encoding/json"
56
"secrets-init/pkg/secrets"
67
"strings"
78

@@ -50,7 +51,20 @@ func (sp *SecretsProvider) ResolveSecrets(ctx context.Context, vars []string) ([
5051
if err != nil {
5152
return vars, errors.Wrap(err, "failed to get secret from AWS Secrets Manager")
5253
}
53-
env = key + "=" + *secret.SecretString
54+
if IsJSON(secret.SecretString) {
55+
var keyValueSecret map[string]string
56+
err = json.Unmarshal([]byte(*secret.SecretString), &keyValueSecret)
57+
if err != nil {
58+
return vars, errors.Wrap(err, "failed to decode key/value secret")
59+
}
60+
for key, value := range keyValueSecret {
61+
e := key + "=" + value
62+
envs = append(envs, e)
63+
}
64+
continue // We continue to not add this ENV variable but only the environment variables that exists in the JSON
65+
} else {
66+
env = key + "=" + *secret.SecretString
67+
}
5468
} else if strings.HasPrefix(value, "arn:aws:ssm") && strings.Contains(value, ":parameter/") {
5569
tokens := strings.Split(value, ":")
5670
// valid parameter ARN arn:aws:ssm:REGION:ACCOUNT:parameter/PATH
@@ -80,3 +94,11 @@ func (sp *SecretsProvider) ResolveSecrets(ctx context.Context, vars []string) ([
8094

8195
return envs, nil
8296
}
97+
98+
func IsJSON(str *string) bool {
99+
if str == nil {
100+
return false
101+
}
102+
var js json.RawMessage
103+
return json.Unmarshal([]byte(*str), &js) == nil
104+
}

pkg/secrets/aws/secrets_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,30 @@ func TestSecretsProvider_ResolveSecrets(t *testing.T) {
6767
return &sp
6868
},
6969
},
70+
{
71+
name: "get all secrets from from Secrets Manager json",
72+
vars: []string{
73+
"test-secret-1=arn:aws:secretsmanager:12345678-json",
74+
},
75+
want: []string{
76+
"TEST_1=test-secret-value-1",
77+
"TEST_2=test-secret-value-2",
78+
},
79+
mockServiceProvider: func(mockSM *mocks.SecretsManagerAPI, mockSSM *mocks.SSMAPI) secrets.Provider {
80+
sp := SecretsProvider{sm: mockSM, ssm: mockSSM}
81+
vars := map[string]string{
82+
"arn:aws:secretsmanager:12345678-json": "{\n \"TEST_1\": \"test-secret-value-1\",\n \"TEST_2\": \"test-secret-value-2\"\n}",
83+
}
84+
for n, v := range vars {
85+
name := n
86+
value := v
87+
valueInput := secretsmanager.GetSecretValueInput{SecretId: &name}
88+
valueOutput := secretsmanager.GetSecretValueOutput{SecretString: &value}
89+
mockSM.On("GetSecretValue", &valueInput).Return(&valueOutput, nil)
90+
}
91+
return &sp
92+
},
93+
},
7094
{
7195
name: "no secrets",
7296
vars: []string{

0 commit comments

Comments
 (0)