Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complex examples needed #72

Open
pascalrobert opened this issue Nov 23, 2022 · 9 comments
Open

Complex examples needed #72

pascalrobert opened this issue Nov 23, 2022 · 9 comments

Comments

@pascalrobert
Copy link

We need more complex examples. For example, how to fetch an key from an item? I tried something like this:

data "onepassword_item" "secrets" {
vault = data.onepassword_vault.aw.uuid
title = "secrets"
}

data.onepassword_item.secrets.section[index(data.onepassword_item.secrets.section.*.label, "my-label")]

Didn't work. Also tried with:

data.onepassword_item.secrets.section[index(data.onepassword_item.secrets.section.*.field.label, "my-label")]

Didn't work either. So what's the correct way to get one key out of an item?

@scottisloud
Copy link

scottisloud commented Nov 25, 2022

Hi Pascal,
I'm Scott, a solutions architect here at 1Password. First, thank you for raising this issue. You're right, although the standard Terraform syntax for referencing nested attributes applies here in theory, the structure of custom 1Password items can make it a bit thorny. We are always working to improve our documentation and we will look for ways to improve our documentation with respect to retrieving specific keys or values from custom sections.

Now, to your specific issue: I'll have to admit that my Terraform chops are very rough, so my response may not be the most efficient way forward, but I've also reached out to the Secrets Automation developer team to see if they have better suggestions. I also hope I understand your question correctly. It sounds to me as if you'd like to retrieve a specific value from a custom field nested in a section. Is that about right?

If so, here's what worked for me, given the following.
I take onepassword_item resource defined in the following way:

resource "onepassword_item" "demo_sections" {
  vault = var.demo_vault

  title    = "Demo Terraform Item with Sections"
  category = "login"
  username = "[email protected]"

  section {
    label = "Terraform_Section"

    field {
      label = "API_KEY"
      type  = "CONCEALED"
      value = "Gr34tP4$$word"
    }

    field {
      label = "HOSTNAME"
      value = "example.com"
    }
  }

  section {
    label = "Terraform Second Section"

    field {
      label = "App Specific Password"
      type  = "CONCEALED"

      password_recipe {
        length  = 40
        symbols = false
      }
    }

    field {
      label = "User"
      value = "demo"
    }
  }
}

And a corresponding data block as follows:

data "onepassword_item" "get_pass_example" {
   vault = var.demo_vault
   uuid  = onepassword_item.demo_sections.uuid
 }

Now I just tested this in terraform console so some tweaks may be required if you're including this in a plan, but the following worked to retrieve the value of the API_KEY field nested in the Terraform_Section section.

data.onepassword_item.get_pass_example.section[index(data.onepassword_item.get_pass_example.section.*.label, "Terraform_Section")].field[0].value

That returns Gr34tP4$$word, as expected.

Now I notice that you are asking for a specific key, rather than values.... if that is actually the case, then you could get an array of keys for the Terraform_Section section:

keys(data.onepassword_item.get_pass_example.section[index(data.onepassword_item.get_pass_example.section.*.label, "Terraform_Section")].field[0])

and a specific key from that array with standard index subscripting on the output from the keys() call. E.g., to get the 0th item:

keys(data.onepassword_item.get_pass_example.section[index(data.onepassword_item.get_pass_example.section.*.label, "Terraform_Section")].field[0])[0]

Now as I said, I'm no Terraform expert myself, so this may be a roundabout way of getting to your destination. I'll pass along any additional suggestions from our developers when available. But hopefully this is a start.

And again, thank you for your suggestions for improving our documentation.

@scottisloud
Copy link

scottisloud commented Nov 28, 2022

Hi Pascal,
First of all, I should apologize, since I think I misunderstood your request when you were asking about retrieving a key. I had assumed you meant "key" in the key/value pair sense.

Alas, one of our devs correctly understood your request and provided the following. The syntax to retrieve the value of the secret is nearly similar to my first value-retrieval syntax but is nested in a more useful output block:

Here’s an example terraform file that gets from an item the value of the field title from section off (the item is looked up by item and vault UUIDs)

terraform {
  required_providers {
    onepassword = {
      source = "1Password/onepassword"
      version = "~> 1.1.4"
    }
  }
}

provider "onepassword" {
  url = "http://localhost:8000/"
}

data "onepassword_item" "example" {
  vault = "ar3v2gmnw73p4bhkphr7t6rv44"
  uuid  = "257ueonb6vek5fg4uwzl2qc73y"
}

output "custom_field" {
    value = data.onepassword_item.example.section[index(data.onepassword_item.example.section.*.label, "off")].field[index(data.onepassword_item.example.section[index(data.onepassword_item.example.section.*.label, "off")].field.*.label, "title")].value
}

There may be a slightly less syntactically-verbose way to drill down into that field but this was what we were able to make work most reliably.

I hope that helps you out a bit!

We'll also file an issue with our docs team to explore options for improving our terraform documentation with respect to this type of task.

@pascalrobert
Copy link
Author

pascalrobert commented Nov 29, 2022

Hi Scott,

Your reply helped a lot, thanks! I did something like this:

data "onepassword_item" "secrets" {
  vault = data.onepassword_vault.aw.uuid
  title = "secrets"
}

locals {
  secrets_bd = data.onepassword_item.secrets.section[index(data.onepassword_item.secrets.section.*.label, "BD")]
}

local.secrets_bd.field[index(local.secrets_bd.field.*.label, "majbds-mdp")].value
``` 

It does work, except if the label or the section name contains a space in it, or the label goes over a specific length, I get errors like this:

│ Error: Error in function call

│ on asg.tf line 95, in module "gabarit_lancement":
│ 95: mp_bd_datadog : local.secrets_bd.field[index(local.secrets_bd.field.*.label, "awDatabase-datadog-mdp")].value,
│ ├────────────────
│ │ while calling index(list, value)
│ │ local.secrets_bd.field is list of object with 7 elements

│ Call to function "index" failed: item not found.

@edif2008
Copy link
Member

edif2008 commented Dec 2, 2022

Heey @pascalrobert,

Glad to see that the suggested snippet that we've suggested worked for you and you even went beyond and made it friendlier. I really appreciate it and we should document such example in the repo as well.

Also, I appreciate that you've identified some scenarios in which the provider doesn't work as expected. I will raise them with my team and try to look into them. We will keep you posted when we have new insight for you regarding these.

@sshipway
Copy link

Thanks for this, I was looking for an example of how to use a custom section.
My problem now is that I haven't seen how to set a custom field of type DATE - the resource completes fine, but the field never appears in the 1password database.

  section {
    label = "Custom"
    field {
      label = "Expiry"
      type  = "DATE"
      value = formatdate("YYYY-MM-DD",expirytimestamp)
    }
  }

@scholdan
Copy link

Hello,

After update to 1.2.0 this no longer works:

resource "onepassword_item" "vm-admin" {
  vault    = data.onepassword_vault.vault.uuid
  title    = lower(var.vm-name)
  category = "login"
  username = "deploy"
  section {
    label = "XXX Data"
    field {
      label   = "Deployment notes"
      purpose = "NOTES"
      value   = "Local admin generated by Terraform"
    }
    field {
      label = "IP"
      type  = "STRING"
      value = phpipam_address.newip.ip_address
    }
  }
  tags = ["terraform", "auto-created", "local-admin", "Linux"]
  password_recipe {
    length  = 40
    symbols = false
  }
}

It does create the "XXX Data" section, but without any data in it.

image

@edif2008
Copy link
Member

edif2008 commented Oct 18, 2023

Hey @scholdan,
We've just merged a fix for that with #100 and we're planning to make a release with this fix soon.

@edif2008
Copy link
Member

edif2008 commented Oct 18, 2023

And the fix has been pushed with the 1.2.1 release. So you should be able to create fields within a section again @scholdan. 😄

@mrkhachaturov
Copy link

mrkhachaturov commented Jun 1, 2024

@pascalrobert @scottisloud, thank you for providing your examples!

I decided to show how I adapted it for my needs. Below is an example of how to retrieve specific data from item.

CleanShot 2024-06-02 at 00 41 35@2x

# Retrieve your vault using the specified name
data "onepassword_vault" "devops_vault" {
  name = var.op_vault
}

# Retrieve the item "Proxmox PVE01" from the main vault
data "onepassword_item" "proxmox_pve01" {
  vault = data.onepassword_vault.devops_vault.uuid
  title = "Proxmox PVE01"
}


locals {
  # Store the section labeled "API" from item  "Proxmox PVE01" in a local variable for shortened string references
  section_api = data.onepassword_item.proxmox_pve01.section[index(data.onepassword_item.proxmox_pve01.section.*.label, "API")]

  # Store the field value of the section "API"  in a local variable for shortened string references
  pve01_api = local.section_api.field
}

# Output the Proxmox PVE01 API URL
output "pm_api_url" {
  value = local.pve01_api[index(local.pve01_api.*.label, "pm_api_url")].value
}

# Output the Proxmox PVE01 API token secret
output "pm_api_token_secret" {
  value = local.pve01_api[index(local.pve01_api.*.label, "pm_api_token_secret")].value
}

# Output the Proxmox PVE01 API token ID
output "pm_api_token_id" {
  value = local.pve01_api[index(local.pve01_api.*.label, "pm_api_token_id")].value
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants