11const process = require ( 'process' )
22
3- const { SecretsManagerClient, ListSecretsCommand, GetSecretValueCommand } = require ( '@aws-sdk/client-secrets-manager' )
3+ const {
4+ SecretsManagerClient,
5+ ListSecretsCommand,
6+ GetSecretValueCommand,
7+ DescribeSecretCommand,
8+ } = require ( '@aws-sdk/client-secrets-manager' )
49const chalk = require ( 'chalk' )
510
611const listSecrets = async ( { client, nextToken, secrets = [ ] } ) => {
@@ -14,23 +19,39 @@ const listSecrets = async ({ client, nextToken, secrets = [] }) => {
1419 return newSecrets
1520}
1621
17- const normalizeSecretValue = async ( { client, secret } ) => {
22+ const getSecretContext = async ( { client, secret } ) => {
23+ try {
24+ const { Tags : tags = [ ] } = await client . send ( new DescribeSecretCommand ( { SecretId : secret . ARN } ) )
25+ const context = tags . find ( ( { Key : key } ) => key === 'NETLIFY_CONTEXT' )
26+ return context && context . Value
27+ } catch ( error ) {
28+ if ( error . name === 'AccessDeniedException' ) {
29+ return console . log (
30+ chalk . dim ( `Does not have permissions to retrieve context for secret ${ chalk . yellow ( secret . Name ) } ` ) ,
31+ )
32+ }
33+ }
34+ }
35+
36+ const getSecretsValue = async ( { client, secret } ) => {
1837 try {
1938 // SecretString is a JSON string representation of the secret, e.g. '{"SECRET_NAME":"SECRET_VALUE"}'
2039 const { SecretString : secretString } = await client . send ( new GetSecretValueCommand ( { SecretId : secret . ARN } ) )
40+ const context = await getSecretContext ( { client, secret } )
2141 const parsedValue = JSON . parse ( secretString )
22- return parsedValue
42+ return Object . entries ( parsedValue ) . map ( ( [ key , value ] ) => ( { key , value , context } ) )
2343 } catch ( error ) {
2444 if ( error . name === 'AccessDeniedException' ) {
25- return console . log ( chalk . dim ( `Skipping restricted AWS secret ${ chalk . yellow ( secret . Name ) } ` ) )
45+ console . log ( chalk . dim ( `Skipping restricted secret ${ chalk . yellow ( secret . Name ) } ` ) )
46+ return [ ]
2647 }
2748 throw error
2849 }
2950}
3051
31- const normalizeSecrets = async ( { client, secrets } ) => {
32- const values = await Promise . all ( secrets . map ( ( secret ) => normalizeSecretValue ( { client, secret } ) ) )
33- return Object . assign ( { } , ... values )
52+ const getSecretsValues = async ( { client, secrets } ) => {
53+ const secretsWithValues = await Promise . all ( secrets . map ( ( secret ) => getSecretsValue ( { client, secret } ) ) )
54+ return secretsWithValues . flat ( )
3455}
3556
3657const SECRET_PREFIX = process . env . NETLIFY_AWS_SECRET_PREFIX || 'NETLIFY_AWS_SECRET_'
@@ -43,6 +64,7 @@ module.exports = {
4364 NETLIFY_AWS_ACCESS_KEY_ID : accessKeyId ,
4465 NETLIFY_AWS_SECRET_ACCESS_KEY : secretAccessKey ,
4566 NETLIFY_AWS_DEFAULT_REGION : region = 'us-east-1' ,
67+ CONTEXT ,
4668 } = process . env
4769 if ( ! accessKeyId ) {
4870 return utils . build . failBuild ( `Missing environment variable NETLIFY_AWS_ACCESS_KEY_ID` )
@@ -57,14 +79,28 @@ module.exports = {
5779 credentials : { accessKeyId, secretAccessKey } ,
5880 } )
5981 const secrets = await listSecrets ( { client } )
60- const normalizedSecrets = await normalizeSecrets ( { client, secrets } )
61-
62- const entries = Object . entries ( normalizedSecrets )
63- entries . forEach ( ( [ key , value ] ) => {
82+ const secretsWithValues = await getSecretsValues ( { client, secrets } )
83+ secretsWithValues . forEach ( ( { key, value, context } ) => {
6484 const prefixedKey = getPrefixedKey ( key )
65- console . log ( `${ chalk . bold ( 'Injecting AWS secret' ) } ${ chalk . magenta ( `${ key } ` ) } as ${ chalk . green ( prefixedKey ) } ` )
66- // eslint-disable-next-line no-param-reassign
67- netlifyConfig . build . environment [ prefixedKey ] = value
85+
86+ // no context, inject to all
87+ if ( ! context ) {
88+ console . log ( `${ chalk . bold ( 'Injecting AWS secret' ) } ${ chalk . magenta ( `${ key } ` ) } as ${ chalk . green ( prefixedKey ) } ` )
89+ // eslint-disable-next-line no-param-reassign
90+ netlifyConfig . build . environment [ prefixedKey ] = value
91+ return
92+ }
93+
94+ // inject only to matching context
95+ if ( CONTEXT === context ) {
96+ console . log (
97+ `${ chalk . bold ( 'Injecting AWS secret' ) } ${ chalk . magenta ( `${ key } ` ) } as ${ chalk . green (
98+ prefixedKey ,
99+ ) } to context ${ chalk . yellow ( context ) } `,
100+ )
101+ /* eslint-disable-next-line no-param-reassign */
102+ netlifyConfig . build . environment [ prefixedKey ] = value
103+ }
68104 } )
69105 } ,
70106}
0 commit comments