Skip to content

Commit

Permalink
interpolate: expose aws_secretsmanager_raw func
Browse files Browse the repository at this point in the history
The current implementation of the aws_secretsmanager function works in
most cases, however there's one missing capability to it: raw fetching a
key-value secret from AWS.

In case the secret is a plaintext secret, the aws_secretsmanager
function will return the secret as-is, ignoring the key completely.

If however the secret is a key-value object, the function fails without
a key being provided, which can be a hassle for users declaring multiple
secrets that they want to fetch at once, as right now they have to
progamatically get the attributes one-by-one with a dynamic/for-loop
expression, or define the function as many times as there are keys to
fetch.

This is not ideal for those users, therefore as introduced with the
parent commit, a new alternative that forces fetching a raw secret from
secretmanager has been added to address this case.
This commit builds upon this change, by exposing the function to the
interpolation context.

This does not make the function available in an HCL2 context however,
and for this we should add that to Packer core.
There also should be a change committed to the AWS plugin so the secrets
manager data source supports this use case in the future.
  • Loading branch information
lbajolet-hashicorp committed Dec 17, 2024
1 parent 80de2ff commit 03a84b5
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions template/interpolate/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,24 @@ func init() {

// Funcs are the interpolation funcs that are available within interpolations.
var FuncGens = map[string]interface{}{
"build_name": funcGenBuildName,
"build_type": funcGenBuildType,
"env": funcGenEnv,
"isotime": funcGenIsotime,
"strftime": funcGenStrftime,
"pwd": funcGenPwd,
"split": funcGenSplitter,
"template_dir": funcGenTemplateDir,
"timestamp": funcGenTimestamp,
"uuid": funcGenUuid,
"user": funcGenUser,
"packer_version": funcGenPackerVersion,
"consul_key": funcGenConsul,
"vault": funcGenVault,
"sed": funcGenSed,
"build": funcGenBuild,
"aws_secretsmanager": funcGenAwsSecrets,
"build_name": funcGenBuildName,
"build_type": funcGenBuildType,
"env": funcGenEnv,
"isotime": funcGenIsotime,
"strftime": funcGenStrftime,
"pwd": funcGenPwd,
"split": funcGenSplitter,
"template_dir": funcGenTemplateDir,
"timestamp": funcGenTimestamp,
"uuid": funcGenUuid,
"user": funcGenUser,
"packer_version": funcGenPackerVersion,
"consul_key": funcGenConsul,
"vault": funcGenVault,
"sed": funcGenSed,
"build": funcGenBuild,
"aws_secretsmanager": funcGenAwsSecrets,
"aws_secretsmanager_raw": funcGenAwsRawSecrets,

"replace": replace,
"replace_all": replace_all,
Expand Down Expand Up @@ -298,6 +299,22 @@ func funcGenAwsSecrets(ctx *Context) interface{} {
}
}

// This function acts essentially like `funcGenAwsSecrets`, with the exception
// that it will always return a plaintext secret, regardless of the type of
// secret.
//
// That is, if the secret is a plaintext, both functions behave the same,
// however, if the secret is an object, this will return the raw JSON object
// from secrets manager, while the alternative errors without a key being specified.
func funcGenAwsRawSecrets(ctx *Context) interface{} {
return func(secretName string) (string, error) {
if !ctx.EnableEnv {
return "", errors.New("AWS Secrets Manager is only allowed in the variables section")
}
return commontpl.GetRawAWSSecret(secretName)
}
}

func funcGenSed(ctx *Context) interface{} {
return func(expression string, inputString string) (string, error) {
return "", errors.New("template function `sed` is deprecated " +
Expand Down

0 comments on commit 03a84b5

Please sign in to comment.