akeyless-community / terraform-provider-akeyless

Mozilla Public License 2.0
12 stars 10 forks source link

Return public key for DFC keys as attributes #25

Closed cmancone closed 2 years ago

cmancone commented 2 years ago

I have a feature request!

For DFC keys, it would be great to have the resource return the public key, as that will often be relevant to use in further terraform resources.

As an example, I can use the terraform provider to create an RSA key and attach it to an SSH cert issuer. However, I then have to go to the AKeyless console, retrieve the public key, and inject that to the machine to establish trust.

If the DFC key itself returns the public key as an attribute then (for instance) I can immediately attach that to the startup script for an AWS instance so that I can both create the SSH cert issuer and establish trust on instances automatically when they launch, all from the same repository and without any manual intervention.

Note that the describe-item API endpoint returns the raw public key, rather than in the "standard" format that the actual SSH program on a linux box expects when establishing trust. It would be easy to add this feature in, except that I'm not sure what the "raw" format is exactly.

Thanks for listening!

devorbitus commented 2 years ago

Hey @cmancone , not sure if you were aware but I think this data resource should allow you to get the public key directly from Terraform without any changes to the provider.

https://github.com/akeyless-community/terraform-provider-akeyless/blob/master/akeyless/data_source_rsa_public.go

We will need to get the documentation updated to reflect this resource as an option.

cmancone commented 2 years ago

Interesting, I didn't! For some reason that isn't in the documentation, and I hadn't noticed it as an option in the AKeyless CLI. Any idea why it doesn't show up in the "official" docs? Is this in an unreleased branch or something? I'm looking here:

https://registry.terraform.io/providers/akeyless-community/akeyless/latest/docs

However, two comments. First, it would be much easier to use if this was returned as part of the dfc key resource. Since it is a separate data source, if I tried to create the key and also use its public key, I'd need a separate dfc resource and data source for the public key. This will likely work fine if everything already exists, but if I'm creating a new key this way, I think that terraform would break, since the data source is referencing a DFC key that doesn't exist yet. I'd have to create the resource with terraform, and then I'd be able to fetch the public key with the data source. For smooth operation, I'm pretty sure that it needs to be returned by the actual resource.

Also, I noticed that there is a bit of an inconsistency in the AKeyless CLI about this call. If I issue a call like this:

akeyless get-rsa-public -n /path/to/key

I get a response like this:

- RAW: MIIBIjANBgkqhkiG9w0BAQEFAAO[TRUNCATED]
- SSH: ssh-rsa AAAAB3NzaC1yc2EAAAAD[TRUNCATED]

However, if I issue this call:

akeyless get-rsa-public -n /services/products/production/bastion_rsa_key --json

I get this very different response for the SSH public key:

{
  "raw": "MIIBIjANBgkqhkiG9w0BAQEFAAO[TRUNCATED]",
  "ssh": "c3NoLXJzYSBBQUFBQjNOem[TRUNCATED]"
}

This is from an actual key, and the part I want to highlight is that the actual value returned for the SSH public key is different when I request output in JSON format. A little digging reveals that one is base64 encoded and the other isn't:

akeyless get-rsa-public -n /services/products/production/bastion_rsa_key --json | jq -r '.ssh' | base64 -d

returns:

ssh-rsa AAAAB3NzaC1yc2EAAAAD[TRUNCATED]

The terraform data source is not doing any base64 encoding, so it's just returning whatever comes back directly from the API endpoint. However, it's not clear to me what the API endpoint returns: the base64 encoded version of the SSH public key, or the base64 decoded one. Therefore, it's not clear to me which one is being returned by the public key data source - if it is returning it as a base64 decoded string, then it won't work.

cmancone commented 2 years ago

Hi @devorbitus,

Do you know if that data source has been released? I'm getting this:

│ Error: Invalid data source
│ 
│   on database/akeyless.tf line 28, in data "akeyless_rsa_public" "bastion":
│   28: data "akeyless_rsa_public" "bastion" {
│ 
│ The provider akeyless-community/akeyless does not support data source "akeyless_rsa_public".

I've tried a few variations based off the Go code, but can't quite seem to find the right one.

devorbitus commented 2 years ago

Hmm, it looks like it was removed around 3 months ago https://github.com/akeyless-community/terraform-provider-akeyless/blob/master/akeyless/provider.go#L177 and just hasn't been brought back yet. Sorry, I should have checked to see if it was actually available before bringing it up

cmancone commented 2 years ago

Any particular reason why it left?

It would definitely be more convenient to have the resource return the public key, but I realized I can still get the job done with a separate data source. I think I can use the data source to fetch the key from a DFC I just created by pointing the depends_on attribute of the data source at the DFC resource. This should tell Terraform to only lookup the public key after the DFC key is created, allowing me to create a Key+Cert issuer and attach it to instances in one repo.

renanaAkeyless commented 2 years ago

added in version 1.1.3