-
Notifications
You must be signed in to change notification settings - Fork 66
SSH resource support #224
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
base: main
Are you sure you want to change the base?
SSH resource support #224
Conversation
|
If you're new to commit signing, there are different ways to set it up: Sign commits with
|
cmrdove
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im no authority on this repository but this looks good and would be great to see it as part of the provider
|
What's preventing this from being approved/merged? It'd be great to start using this! |
volodymyrZotov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for putting this together 👍 I love this initiative, though I found several issues while testing current implementation (see comments).
And there are more findings here:
- It requires to set
passwordfiled in to resource definition in order toterraform applysucceed. We need to make it optional forssh_keycategory. - After initial
terraform applysucceeded and running it second time threw and error
│ Error: 1Password Item read error
│
│ with onepassword_item.key3,
│ on main.tf line 18, in resource "onepassword_item" "key3":
│ 18: resource "onepassword_item" "key3" {
│
│ Could not get item 'item_id' from vault 'vault_id',
│ got error: op error: "private_key" isn't a field in the "key3" item
- Right now
private_keysuppose to be provided as a string, which is not very convenient, I think. I'd like to see there a possibility to provide configuration and autogenerate the key (similar as we do for password).
# example
private_key_recipie {
type: "ed25519"
}
- When I copy a private key directly from 1password or from local as multiline string (with
\nnew lines)
-----BEGIN OPENSSH PRIVATE KEY-----
key
-----END OPENSSH PRIVATE KEY-----
and run terrafrom apply it doesn't create an item, as \n breaks the command. See output below
var.private_key
Enter a value: -----BEGIN OPENSSH PRIVATE KEY-----
QyNTUxOQAAACAFtzW7Wz2bp6nqPQcvWnloxALsrbdSgaAwetNnsrOYwAAAAIiHybtoh8m7
aAAAAAtzc2gtZWQyNTUxOQAAACAFtzW7Wz2bp6nqPQcvWnloxALsrbdSgaAwetNnsrOYwA
..........
-----END OPENSSH PRIVATE KEY-----
data.onepassword_vault.vault: Reading...
data.onepassword_vault.vault: Read complete after 1s [id=vaults/redacted]
Terraform used the selected providers to generate the following execution plan. Resource
actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# onepassword_item.key3 will be created
+ resource "onepassword_item" "key3" {
+ category = "ssh_key"
+ id = (known after apply)
+ password = (sensitive value)
+ private_key = (sensitive value)
+ public_key = "redacted"
+ title = "key3"
+ uuid = (known after apply)
+ vault = "redacted"
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Apply cancelled.
~/Projects/test/tf-ssh-resource/test
$ QyNTUxOQAAACAFtzW7Wz2bp6nqPQcvWnloxALsrbdSgaAwetNnsrOYwAAAAIiHybtoh8m7
zsh: command not found: QyNTUxOQAAACAFtzW7Wz2bp6nqPQcvWnloxALsrbdSgaAwetNnsrOYwAAAAIiHybtoh8m7
~/Projects/test/tf-ssh-resource/test
$ aAAAAAtzc2gtZWQyNTUxOQAAACAFtzW7Wz2bp6nqPQcvWnloxALsrbdSgaAwetNnsrOYwA
zsh: command not found: aAAAAAtzc2gtZWQyNTUxOQAAACAFtzW7Wz2bp6nqPQcvWnloxALsrbdSgaAwetNnsrOYwA
Please let me know if you need any help with that.
| ### Optional | ||
|
|
||
| - `category` (String) The category of the item. One of ["login" "password" "database" "secure_note"] | ||
| - `category` (String) The category of the item. One of ["login" "password" "database" "secure_note" "ssh_key"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ssh_key category should be added to internal/provider/const.go as well.
| - `private_key` (String, Sensitive) SSH Private Key for this item. | ||
| - `public_key` (String) SSH Public Key for this item. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connect sdk that the provider uses appears to have some issues creating ssh keys. I've noticed that in testing this fork, ssh keys I create via connect cannot be read back by op cli; when I try the cli gives this error:
[ERROR] 2025/10/24 16:47:19 "private_key" isn't a field in the "Example SSH Key Item" item
This causes issues because op cli (or terraform connecting via service account rather than via connect) cannot delete/modify the resulting resource.
I can't see a 'proper' way to create SSH keys via connect. Everything I try results in a record op cli cannot process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the same is true for items created via service account. The resulting item cannot be read by op cli, causing terraform destroy to fail:
│ Error: 1Password Item read error │ │ with onepassword_item.demo_ssh_key, │ on main.tf line 127, in resource "onepassword_item" "demo_ssh_key": │ 127: resource "onepassword_item" "demo_ssh_key" { │ │ Could not get item 'snip' from vault 'snip', got error: op error: "private_key" isn't a field in the "Example Terraform SSH Key Item" item
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have got my fork working for generating an SSH key from scratch when using a service account:
i.e. in OP.create:
...
if item.Category == onepassword.SSHKey {
return op.createSSHKey(ctx, item, vaultUuid)
}
...and then a new method for ssh keys:
func (op *OP) createSSHKey(ctx context.Context, item *onepassword.Item, vaultUuid string) (*onepassword.Item, error) {
args := []opArg{
p("item"), p("create"),
f("category", "SSH Key"),
f("title", item.Title),
f("vault", vaultUuid),
}
if len(item.Tags) > 0 {
args = append(args, f("tags", strings.Join(item.Tags, ",")))
}
var res *onepassword.Item
err := op.execJson(ctx, &res, nil, args...)
if err != nil {
return nil, err
}
return res, nil
}I will revisit the logic for when we use 1Password Connect on Monday, but I think it will require a patch to the connect SDK to work consistently there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've logged the following for Connect: https://github.com/1Password/onepassword-sdk-go/issues/216
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@twbrowning @volodymyrZotov, thanks for reviewing this! Unfortunately I've had to deprioritize my Terraform work for now. If you have any ideas on how to solve the issues, and properly integrate with the Connect server, then feel free to submit patches to this branch. Otherwise I will pick this up when I can return to Terraform again.


This PR builds on the work by @atammy-narmi for introducing SSH as a data source, whereas we here also add it as a resource.
My use case for this is to enable having all SSH key secrets stored inside a 1Password vault, and entirely forego the TF state for this sensitive information.