1Password/terraform-provider-onepassword

Using terraform cloud with 'local-exec' provisioner to install OP CLI?

josh-burton opened this issue ยท 12 comments

Your environment

Terraform Cloud

Connect Server Version: None

CLI Version: any

OS: Ubuntu

Terraform Version:

What happened?

Can anyone give me an example of using a 'local-exec' provisioner to install the OP CLI when using Terraform Cloud?

I'm unable to get it to work. I keep getting the following error:

 failed to get version of op CLI: failed to execute command: exec: "op": executable file not found in $PATH

What did you expect to happen?

Steps to reproduce

Notes & Logs

@josh-burton Thanks for raising this.

Only Install Standalone Binaries article might be helpful to understand how you can add additional binaries. And this one Install 1Password CLI.

Please let us know how it goes for you.

@josh-burton Thanks for raising this.

Only Install Standalone Binaries article might be helpful to understand how you can add additional binaries. And this one Install 1Password CLI.

Please let us know how it goes for you.

Yes I have seen those and attempted to set that up but as far as I can see the local-exec provisioner is never invoked.

It seems that the 1password provider is attempting to read the op version in the provider block, before the provisioner has been invoked?

@josh-burton Correct. Do you think that's why it doesn't work on cloud? Looks like we can either skip the version check at all, as CLI will throw an error anyway if <v2.23.0 is used, or move the version check inside func (op *OP) execRaw and do it for every command.

We'll take a close look to check that, but if you have a chance, feel free to open a PR with the changes that might fix the problem ๐Ÿ˜ƒ. Not sure, though, if you'll be able to test it with the local build. Anyway, we can make a beta version for that purpose.

Here is CONTRIBUTING.md if you decide to do so.

Thank you once again ๐Ÿ‘

@josh-burton released your fix in v1.4.1-beta01 ๐Ÿš€. I'll check if that helped. Feel free to try it too if you have a chance and let me know whether it works for you.

Good news - this definitely helps things and I've managed to update 1password items via terraform cloud.

There is one gotcha - the provisioner is not run during a refresh, so once an item has been created, the next time the plan is run it is failing due to not finding the op cli.

I'm not sure how to solve this.

I've ended up committing the op cli binary to the repo and that is now working. Not ideal though!

@josh-burton I'm glad that you managed to make it work! Did you manage to make it work using provisioner? Don't you mind to share the snippet? ๐Ÿ™‚

I think that to make it work on cloud without any additional configuration the provider can install the cli during initialization. So it requires no additional effort from the users. We will think about better solution for this. Thanks for raising this again, and the contribution! ๐Ÿ‘

@josh-burton I'm glad that you managed to make it work! Did you manage to make it work using provisioner? Don't you mind to share the snippet? ๐Ÿ™‚

I think that to make it work on cloud without any additional configuration the provider can install the cli during initialization. So it requires no additional effort from the users. We will think about better solution for this. Thanks for raising this again, and the contribution! ๐Ÿ‘

That sounds like a great long term solution.

Here's the cli installation block that is working for me:

resource "terraform_data" "install_op_cli" {
  input = timestamp()

  triggers_replace = [
    timestamp()
  ]

  provisioner "local-exec" {
    command = <<EOH
ARCH="amd64"; \
    OP_VERSION="v$(curl https://app-updates.agilebits.com/check/1/0/CLI2/en/2.0.0/N -s | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')"; \
    curl -sSfo op.zip \
    https://cache.agilebits.com/dist/1P/op2/pkg/"$OP_VERSION"/op_linux_"$ARCH"_"$OP_VERSION".zip \
    && mkdir tools \
    && unzip -od tools op.zip \
    && rm op.zip \
    && chmod 0755 tools/op \
    && export PATH="$PATH:$(pwd)/tools" \
    && echo $PATH \
    && op --version
EOH
  }
}

Any resource that uses onepassword should depend on this. It's configured to be replaced on every run so the CLI is always available (except in the plan/refresh step as mention above).

Future work on that will be done in scope of #141

@josh-burton I've been trying to get this to work for me, but can't get it to reference the op cli I am including in my repo, are you able to show how you managed to get it to work?

@tristal My setup is:

In modules/onepassword/main.tf

provider "onepassword" {
  token                 = null
  service_account_token = var.OP_SERVICE_ACCOUNT_TOKEN
  op_cli_path           = "tools/op"
}

And my directory structure is:

/root
		- modules
						- onepassword
		-tools
				- op (binary)

Note that the op binary needs to be the correct architecture for running on Terraform cloud runners, which I think is the linux arm64 version.

I just wanted to come back to this, and indicate that the tools/op is relative to dir of your TF code, that is what was causing my issue.

/
/modules/onepassword
/some-project/file.tf
/some-project/tools/op

I was able to place the binary at the root and create a symlink to the project(s) that use it.

/
/modules/onepassword
/some-project/file.tf
/some-project/tools/op (symlink to /tools)
/another-project/file.tf
/another-project/tools/op (symlink to /tools)
/tools/op