Is there an established way to store a value that ...
# getting-started
l
Is there an established way to store a value that is only set on first deployment, then isn't changed unless the keepers are changed? eg I'd like to get the most recent AMI ID from SSM on initial deployment, but then pin that ID unless I tell it to be updated. I came up with an amusing way to abuse the Random package for this, but it feels _wrong_:
Copy code
/**
 * A string that will only be set once and will not change on subsequent updates, even if the input changes.
 * The 'keepers' field can be used to force a new value to be used.
 */
export class PersistentString extends random.RandomShuffle {
  constructor (name: string, input: PersistentStringArgs, opts?: pulumi.CustomResourceOptions) {
    super(name, {
      inputs: [input.value],
      resultCount: 1,
      keepers: input.keepers
    }, pulumi.mergeOptions(opts, { ignoreChanges: ['inputs'] }))
  }
}
q
Couldn't you use
ignoreChanges
directly on the resource where you're setting the AMI ID?
l
I could, but then in order to force an update I'd need to remove the ignoreChanges and then re-apply it again later. I was hoping to mainly take advantage of the 'keepers'
q
The only other option I can think of right now would be splitting this into two stacks. The first one fetches the AMI ID from SSM and exports it as an output. The second one uses a stack reference to use that output. This might be a bit too decoupled depending on your setup
l
That's a potential option - Thanks for your input
c
You could probably pull that off with a dynamic provider/resource. Basically, use its
create
method to return a result with the initial AMI ID and also always the same ID from the update too until you change the
keepers
input to the dynamic resource. The
diff
method in the provider callback allows you to detect which property changed. So when the
keepers
property changes, trigger another call to fetch the AMI ID from SSM again.
l
The only other option I can think of right now would be splitting this into two stacks.
Projects 🙂
h
I've used the command provider to do this:
Copy code
const sample = Date.now(); // changes every time run
const trigger = 1; // but only captured when this value changes

const cache = new command.local.Command("cache", {
    create: pulumi.interpolate`echo "${sample}"`,
    triggers: [trigger],
}, { ignoreChanges: ["create"] })

export const output = cache.stdout;