pulumi / circleci

CircleCI Orbs for CI/CD using Pulumi.
Apache License 2.0
20 stars 15 forks source link

Add `pulumi stack output` orb to introduce new CircleCI variable #15

Closed chrsmith closed 4 years ago

chrsmith commented 5 years ago

The pulumi stack output command prints the "outputs" of the currently selected stack.

For example (with some censoring):

$ pulumi stack output
Current stack outputs (8):
    OUTPUT                     VALUE
    albDnsName                 alb-xxx-xxx.us-xxx-1.elb.amazonaws.com
    apiServiceName             api--xxx
    apiServiceRepoUrl          xxx.dkr.ecr.us-xxx-2.amazonaws.com/api-repo-xxx
    autoScalingGroupStackName  autoScalingGroupStack-d691f8c
    consoleServiceRepoUrl      xxx.dkr.ecr.us-xxx-2.amazonaws.com/xxx
    databaseClusterEndpoint    tf-201910xxx.cluster-xxx.us-xxx-1.rds.amazonaws.com
    databaseClusterId          tf-2019xxxxx
    ecsClusterName             chris--xxx

$ pulumi stack output "apiServiceRepoUrl"
xxx.dkr.ecr.us-xxx-2.amazonaws.com/xxx

This is primarily used to automate/script things based on a stack. For example, running tests against the stack's API endpoint. Or copying data to a database or something.

Adding an orb like this would be super useful, especially if it could be used to introduce or declare some variable in the CircleCI configuration.

i.e. the equivalent of: export TEST_URL=$(pulumi stack output "apiEndpointUrl")

See documentation for the commands at: https://www.pulumi.com/docs/reference/cli/pulumi_stack_output/

kenfdev commented 5 years ago

I'll take this 👍

kenfdev commented 5 years ago

hmm... I'm wondering how this orb can be used. Your example from #14 about a review_app is as follows:

review_app_example:
    description:
         "Creates a new Pulumi stack and deploys the source code built as part of the workflow, running
           tests against it. When complete, tears down the stack and cleans up any cloud resources."
    usage:
        ...
    steps:
        - checkout
        - build # ?
        - pulumi/login
        - pulumi/stack_init:
            stack: robot-co/test-pr_<< include CircleCI job number? >>
        - pulumi/stack_update
        - # export TEST_URL=$(pulumi stack output "awsLambdaUrl")?
        - run_tests $TEST_URL
      on_complete:
          - pulumi/destroy
          - pulumi/stack_rm:
              stack: << include CircleCI job number? >>

Assuming this orb will be called pulumi/stack_output, how would one use the output for further jobs?

Will it be something like this?

pulumi/stack_output
  property_name: foo
  set_env_var: FOO
chrsmith commented 5 years ago

Will it be something like this?

pulumi/stack_output:
    property_name: foo
    set_env_var: FOO

Yes, though for consistency you'd probably want to add a stack parameter as well. (Since all of our other orbs require it to be specified, even though technically it may be optional.)

I think the hard part would be figuring out how to "export" that property value within CircleCI's configuration language. Since IIRC, environment variables were treated in special ways. So we don't necessary have to set an environment variable, we just need to pass some data around. CircleCI may have some other way of introducing new values for the remaining lifetime of a job/workflow.

kenfdev commented 5 years ago

I think the hard part would be figuring out how to "export" that property value within CircleCI's configuration language

Yes, this part is probably the tricky part. Let me search other orbs to see how this is accomplished.

aengelberg commented 5 years ago

If you want to share data between jobs in a workflow... CircleCI's workspaces feature is the best supported way to persist state between jobs in a workflow. It's an append-only directory of files that lasts for the duration of the workspace and is passed around between jobs, letting you share data by writing/reading files. There's a deep dive of the feature on our blog.

If you want to share data between steps in a job... You're right that export variables don't really work here, because each step creates its own shell, so all the exports go away. Therefore we allow appending export statements to BASH_ENV, which is basically the .bashrc of your container, to make exports last throughout the remainder of a job.

I actually wrote my own orb over the weekend called rememborb which combines these strategies to make it as easy as possible to hold onto environment variables. You could potentially take some inspiration from the source code of that orb or depend on it directly.

kenfdev commented 4 years ago

Forgot to close this issue via the PR. Thi issue can be closed now 😉