Venafi / terraform-provider-venafi

HashiCorp Terraform provider that uses Venafi to streamline machine identity (certificate and key) acquisition.
https://www.terraform.io/docs/providers/venafi/
Mozilla Public License 2.0
16 stars 20 forks source link

Terraform Import venafi_certificate fails because its requires 2 arguments #95

Closed zohairajmal closed 1 year ago

zohairajmal commented 1 year ago

Venafi Provider. Here we can see that it requires 2 arguments for terraform import. However, on the terraform documentation, it states that the key_password is an optional variable. Inside the statefile if none is set, the value is : null.

The problem comes when importing the certificate on terraform. The common_name is not enough for it to import this resource. There should be a way to import a certificate without a key_password, maybe feeding key_password as null should do it? WDYT. Do I have to have a key_password for the resource for it to be imported?

If I try to generate a password with terraform and later use that to import the resource, it says: Error: unable to retrieve: Unexpected status code on TPP Certificate Retrieval. Status: 400 Failed to lookup private key, error: Failed to lookup private key vault id - private key was service generated? Import method does not support importing of local generated private keys

luispresuelVenafi commented 1 year ago

Hi @zohairajmal , thank you for reaching out! Yes, the key_password is an optional value in the resource creation process but it is required during the import process since it is part of our import ID as mentioned in the import section in our provider documentation: https://registry.terraform.io/providers/Venafi/venafi/latest/docs/resources/venafi_certificate#import

The import_id is different for each platform, for TPP it does conform the common_name and the key_password while VaaS conforms a Certificate ID and the key_password. We would need to research about the implications of managing two types of import ID's within the provider. How impactful it is for your use case? Is it an enhancement you would like to see in the provider (having the ability to not provide a key-password during the import process)?

Due to the error is safe to assume that you were using TPP, are you importing a certificate the has its key-pair generated by the service? Our import process currently only supports the importing of certificate the were service generated (for our provider we support only local and service modes to create a certificate key-pair, the default one is local.

zohairajmal commented 1 year ago

Hello @luispresuelVenafi thank you for reaching back to me.

I am actually working on an automation that makes the import process automatic, hence the terraform import is not being done by any human. The way I get the import ID is via Venafi API where I make an API call to Venafi with a common_name to confirm that the resource exists in real world infrastructure. If the common_name is a match in the terraform plan step and the one in Venafi TPP portal, it automatically imports the resource. Now for this, we are not using any key_password for the resource of venafi_certificate. This can be an enhancement on your end to update the provider version to support a different import ID within the provider.

Yes, I am using the TPP platform. I am basically generating a Venafi certificate within Terraform without any key-pair, just running a basic example as shown on Terraform docs without any optional arguments (i.e Just common_name) and am trying to import this.

Im not sure if I understand the last paragraph, I do generate the certificate using Terraform and only common_name, which I would assume be (service generated)?. Would you recommend any solution on importing the resource? I can implement the resource to have key_password but how can it be generated inside Terraform itself? and can the key_password be queried via an API? (im guessing not).

zohairajmal commented 1 year ago

To give further information on how to reproduce:

terraform {
  required_providers {
    venafi = {
      source  = "venafi/venafi"
      version = "~> 0.15.5"
    }
  }
}

provider "venafi" {
  url          = "..."
  zone         = "...\\Infrastructure As Code"
  access_token = "..."
}

resource "venafi_certificate" "example" {
  common_name = "app1.demo.net"
  key_password = "SomeKeyPassword123!"
}

Doing terraform apply on the above configuration creates a certificate on venafi portal as well. Now in my case, we corrupt the statefile and remove the venafi resource from the statefile. Or import this resource into a new statefile by doing: terraform import venafi_certificate.example app1.demo.net,SomeKeyPassword123! it returns the error that I had mentioned above (400 error failed to lookup).

It would be easier if we dont have to generate a key_password on terraform for this resource when importing as we want to make it automatic as possible. Let me know what the team thinks about it.

luispresuelVenafi commented 1 year ago

Hello @zohairajmal , sorry for the delay

Im not sure if I understand the last paragraph, I do generate the certificate using Terraform and only common_name, which I would assume be (service generated)?.

Generally when managing PKI infrastructure you'd want to pass your CSR and its private key to any of the platforms in order to perform the issuance of a Certificate Key-pair. This is, you'd store your private key locally. Now, we have support the ability to get the CSR key-pair generated by the service (by either Venafi as a Service, or Venafi's Trust Protection Platform) in order to have the private key also stored in any of the previous mentioned platforms.

In Terraform this translates to having your private keys only in your Terraform state when setting the csr_origin to local (as mentioned in the documentation arguments section), you would manage your private keys by either encrypted at REST or by securing the machine where your private keys are stored. By setting csr_origin to service you would then generate your CSR key-pair using the service, so the private key would be stored in your Terraform file and also in the platform.

Would you recommend any solution on importing the resource?

For your use case scenario I'd then recommend setting that csr_origin to service since the default one is local, since at the time being, we don't support importing a certificate in local "mode", which seems to be the your case since you didn't explicitly defined that attribute (that's why the error was stating about private key was service generated? since it didn't find the private key stored in the platform).

Since you are implementing an automation, you could store your key_password that is going to use in an environment variable or you could extract it from the Terraform resource once it has been created.

A side note: The key_password enforcement is made from the endpoints that we use for retrieving the certificate the key-pair and we decided to follow it because of best practices and we didn't provide a version without because of the implication of two different types of import ID's. That said, we could take research and look at that what we can do to not provide a key_password during the import process.

Or import this resource into a new statefile by doing: terraform import venafi_certificate.example app1.demo.net,SomeKeyPassword123! it returns the error that I had mentioned above (400 error failed to lookup).

This error should be solved once you set csr_origin attribute of the resource to service.

I can implement the resource to have key_password but how can it be generated inside Terraform itself?

The key_password will be part of the attributes of the resource, so you could extract it by using local provisioner to set the key_password to a file and then read it in bash; you could also read it from the state using terraform state command; or since you mentioned you were tempering with terraform's state file, you could read the file in order to read that value after the resource have been created.

and can the key_password be queried via an API? (im guessing not).

You are right, it cannot be queried from the API. It would be a security flaw to return the key_password from an API endpoint.

luispresuelVenafi commented 1 year ago

Hi @zohairajmal , were you able to solve your issue with the above comments?

zohairajmal commented 1 year ago

@luispresuelVenafi I was able to proceed forward but I cannot confirm this yet because when creating the resource, I get some error with pbsc12 not supported. I think it has something to do with the Venafi TPP having md5 PBE instead of SHA256, i have informed the respective team to change it to SHA256 and they are measuring the impact of this change right now (this was a suggestion from one of the closed issues here) to solve the problem. I will let you know here if the creation + import was successful after that has been done soon enough.

zohairajmal commented 1 year ago

The Issue seems to be solved for now by moving out PBE to SHA256, the import works fine with the key_password! Ofc the only problem we see is that the key_password that we use is a Password stored in Jenkins as an environment variable that is rotating every year. Will think of a more permanent solution till then.

harouny commented 11 months ago

Hi @zohairajmal , thank you for reaching out! Yes, the key_password is an optional value in the resource creation process but it is required during the import process since it is part of our import ID as mentioned in the import section in our provider documentation: https://registry.terraform.io/providers/Venafi/venafi/latest/docs/resources/venafi_certificate#import

The import_id is different for each platform, for TPP it does conform the common_name and the key_password while VaaS conforms a Certificate ID and the key_password. We would need to research about the implications of managing two types of import ID's within the provider. How impactful it is for your use case? Is it an enhancement you would like to see in the provider (having the ability to not provide a key-password during the import process)?

Due to the error is safe to assume that you were using TPP, are you importing a certificate the has its key-pair generated by the service? Our import process currently only supports the importing of certificate the were service generated (for our provider we support only local and service modes to create a certificate key-pair, the default one is local.

Hi @luispresuelVenafi I have two questions (we're using VaaS):

harouny commented 11 months ago

Hi @luispresuelVenafi

I managed to get an answer myself:

How to get Certificate ID for portal (to use in terraform import)?

I got that id from certificate requests page in the portal, click on a specific request and the id will be in browser location bar.

What if the the password that was used when creating the certificate was lost or not stored in the first place...how can we do terraform import in that case?

I thought the password is an existing password provided when creating the certificate in the first place. Turned out to be just a new password to encrypt the imported key so all good