terraform-provider-onepassword icon indicating copy to clipboard operation
terraform-provider-onepassword copied to clipboard

Run provider on Terraform Cloud

Open volodymyrZotov opened this issue 1 year ago • 5 comments

Summary

With the latest stable version v1.4.0 it's not possible to run the provider on Terraform Cloud.

The attempt to fix it was done in v1.4.1-beta01, but requires additional efforts from the user to make it work. See details in this thead

The purpose of this issue to make the usage on Terraform Cloud smooth for the users and in the way that requires minimal efforts to run it.

Use cases

Run provider on Terraform Cloud.

Proposed solution

If the provider is running on the Terraform Cloud, install op-cli during provider initialization and use it. The minimum OP CLI version should be v2.23.0.

Is there a workaround to accomplish this today?

Commit the op binary to the repo. Here is the code snippet to give you a general idea of how to install the op binary (additional changes might be required to make it work for you).

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
  }
}

References & Prior Work

#116

volodymyrZotov avatar Jan 17 '24 02:01 volodymyrZotov

The following Dockerfile can build a custom tfc-agent image to provide op out of the box. However, this only works if you pay for custom runners in TFC.

ARG TFC_AGENT_VERSION
FROM hashicorp/tfc-agent:${TFC_AGENT_VERSION}

USER root

RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    gnupg \
    ca-certificates \
    apt-transport-https \
    debsig-verify

# https://developer.1password.com/docs/cli/get-started/#step-1-install-1password-cli
RUN curl -sS https://downloads.1password.com/linux/keys/1password.asc | \
    gpg --dearmor --output /usr/share/keyrings/1password-archive-keyring.gpg

RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/1password-archive-keyring.gpg] https://downloads.1password.com/linux/debian/$(dpkg --print-architecture) stable main" | \
    tee /etc/apt/sources.list.d/1password.list

RUN mkdir -p /etc/debsig/policies/AC2D62742012EA22/
RUN curl -sS https://downloads.1password.com/linux/debian/debsig/1password.pol | \
    tee /etc/debsig/policies/AC2D62742012EA22/1password.pol

RUN mkdir -p /usr/share/debsig/keyrings/AC2D62742012EA22
RUN curl -sS https://downloads.1password.com/linux/keys/1password.asc | \
    gpg --dearmor --output /usr/share/debsig/keyrings/AC2D62742012EA22/debsig.gpg

RUN apt-get update && apt-get install -y 1password-cli
RUN rm -rf /var/lib/apt/lists/*

USER tfc-agent

hollow avatar Jan 23 '24 07:01 hollow

To make this work on cloud and self hosted agents, you can use this workaround that we've been using on TFC for a long time now.

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
  }
}

provider "onepassword" {
  # ...
  op_cli_path           = "./tools/op"
}

If you want a specific version, you can tweak as needed.

MXfive avatar Apr 11 '24 02:04 MXfive

@MXfive how do you handle subsequent plan runs where it tries to read the previously created resources? I was able to create the resource without issues in the plan stage as long as I have depends_on = [terraform_data.install_op_cli] but follow-up plan runs result in

Error: 1Password Item read error
│ 
│   with onepassword_item.test,
│   on 1password_test.tf line 47, in resource "onepassword_item" "test":
│   47: resource "onepassword_item" "test" {
│ 
│ Could not get item '<redacted>' from vault
│ '<redacted>', got error: failed to get version of op CLI:
│ failed to execute command: fork/exec ./tools/op: no such file or directory
╵
Operation failed: failed running terraform plan (exit 1)

stmyers avatar Jun 05 '24 20:06 stmyers

@MXfive how do you handle subsequent plan runs where it tries to read the previously created resources? I was able to create the resource without issues in the plan stage as long as I have depends_on = [terraform_data.install_op_cli] but follow-up plan runs result in

Error: 1Password Item read error
│ 
│   with onepassword_item.test,
│   on 1password_test.tf line 47, in resource "onepassword_item" "test":
│   47: resource "onepassword_item" "test" {
│ 
│ Could not get item '<redacted>' from vault
│ '<redacted>', got error: failed to get version of op CLI:
│ failed to execute command: fork/exec ./tools/op: no such file or directory
╵
Operation failed: failed running terraform plan (exit 1)

Ah that really sucks. I'm only using the data source, not resource. So its expected to not be known at plan time.

MXfive avatar Jun 05 '24 22:06 MXfive

@volodymyrZotov could you please add "Commiting the op binary to the repo" as workaround in the issue description?

ei-grad avatar Jul 09 '24 11:07 ei-grad