Skip to content

Instantly share code, notes, and snippets.

@danielrbradley
Created October 25, 2019 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielrbradley/0a9e661379efd4fbfd19a63434d5a08d to your computer and use it in GitHub Desktop.
Save danielrbradley/0a9e661379efd4fbfd19a63434d5a08d to your computer and use it in GitHub Desktop.
Pulumi custom component for running local commands

Use case

This can be useful for running a custom build command to generate assets which will be used as part of your Pulumi deployment.

Example

Run a command, specifying ENV variables based on the output of another resource.

const clientBuild = new Exec('demo-client-build', {
  command: 'cd ../client && yarn build',
  options: {
    env: pulumi
      .all([userPool.id, authClient.id])
      .apply(([cognitoUserPoolId, userPoolWebClientId]) =>
        Object.assign(
          {
            REACT_APP_USER_POOL_ID: cognitoUserPoolId,
            REACT_APP_USER_POOL_WEB_CLIENT_ID: userPoolWebClientId,
          },
          process.env,
        ),
      ),
  },
});

This resource can then be explicitly depended on to ensure it completes before subsequent steps.

import * as pulumi from '@pulumi/pulumi';
import { exec, ExecOptions } from 'child_process';
export type ExecArgs = {
command: pulumi.Input<string>;
options?: pulumi.Lifted<ExecOptions>;
};
export class Exec extends pulumi.ComponentResource {
stdout: pulumi.Output<string>;
stderr: pulumi.Output<string>;
constructor(
name: string,
args: ExecArgs,
opts?: pulumi.ComponentResourceOptions,
) {
super('local:child_process:Exec', name, {}, opts);
const result = pulumi.all([args.command, args.options || {}]).apply(([command, options]) =>
new Promise<[string, string]>((resolve, reject) => {
exec(command, options, (err, stdout, stderr) => {
if (err !== null) {
reject(err);
} else {
resolve([stdout, stderr]);
}
});
}),);
this.stdout = result.apply(([stdout,]) => stdout);
this.stderr = result.apply(([,stderr]) => stderr);
this.registerOutputs({
stdout: this.stdout,
stderr: this.stderr,
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment