Coder Social home page Coder Social logo

terraform-provider-acme-old's Introduction

This project is now archived. The new location of the project can be found here!

Terraform ACME Provider

This is the repository for the Terraform ACME Provider, which one can use with Terraform to manage and generate certificates generated by an ACME CA, such as Let's Encrypt.

For general information about Terraform, visit the official website and the GitHub project page.

โš ๏ธ NOTE: The ACME provider as of version 1.0.0 supports ACME v2 only. For ACME v1 endpoints, version 0.6.0 is required, which can be found here.

Installation Instructions

The ACME provider is currently a 3rd party plugin. See the documentation on 3rd party plugins for installation instructions, and download the latest release from the releases page.

Distributions with direct installation support

If you use Arch Linux, the terraform-provider-acme-bin package is available via the AUR and can be installed via an AUR-supported package manager such as yay. Thanks to @SamWhited for this!

Example with yay:

yay -S terraform-provider-acme-bin

Documentation

Documentation can be found in the doc directory.

License

Copyright 2018 Chris Marchesi
Copyright 2016-2018 PayByPhone Technologies, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

terraform-provider-acme-old's People

Contributors

abn avatar byt3bl33d3r avatar counterbeing avatar mrsimo avatar vancluever avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-provider-acme-old's Issues

provider not found, provider is there - v0.92

I tried to follow this: https://opencredo.com/letsencrypt-terraform/

When using latest version terraform v 0.92 I get this error:

Error asking for user input: 2 error(s) occurred:

* module.acme-reg.acme_registration.reg: provider acme couldn't be found
* module.acme-cert.acme_certificate.certificate: provider acme couldn't be found

But see:

$ terraform-provider-acme 
This binary is a plugin. These are not meant to be executed directly.
Please execute the program that consumes these plugins, which will
load any plugins automatically

It ended up working with an older version (same used in the blogpost shown). I saw #9 -- wonder if similar update is required again for 0.92?

acme_certificate: State migration

The schema of acme_certificate will be changing as well as we drop the HTTP and TLS challenges. State migration should happen to remove these fields.

Note that nothing else is changing in acme_certificate, so this should not be a complex operation.

How to register the letsencrypt certificate to AWS Certificate Manager

I'd like to import self-sign or free certificate into AWS Certificate Manager by terraform
(https://aws.amazon.com/certificate-manager/) and I found this ACME provider.

I have successfully applied the change with the full example (https://github.com/paybyphone/terraform-provider-acme#full-example-with-certificate_request_pem-and-dns-validation)

Now what should I do? How to provide below informations ?

Certificate body
Certificate private key
Certificate chain

Check the tfstate file, there is a resource acme_certificate.certificate generated with several pem key, how to use them?


                "acme_certificate.certificate": {
                    "type": "acme_certificate",
                    "depends_on": [
                        "acme_registration.reg",
                        "tls_cert_request.req",
                        "tls_private_key.reg_private_key"
                    ],
                    "primary": {
                        "id": "https://acme-v01.api.letsencrypt.org/acme/cert/xxxx",
                        "attributes": {
                            "account_key_pem": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAtjLxxxxV2dlT0EpeNWbvuydrc6Xf6PL\n-----END RSA PRIVATE KEY-----\n",
                            "account_ref": "https://acme-v01.api.letsencrypt.org/acme/reg/xxx",
                            "certificate_domain": "stag.newsnow.io",
                            "certificate_pem": "-----BEGIN CERTIFICATE-----\nMIIFGDCCBACgAwIBxxxxkaLBVsGY6vA=\n-----END CERTIFICATE REQUEST-----\n",
                            "certificate_url": "https://acme-v01.api.letsencrypt.org/acme/cert/031408ad563ff33291d02f21bdd3e2a3c595",
                            "dns_challenge.#": "1",
                            "dns_challenge.1056487162.config.%": "0",
                            "dns_challenge.1056487162.provider": "route53",
                            "http_challenge_port": "80",
                            "id": "https://acme-v01.api.letsencrypt.org/acme/cert/031408ad563ff33291d02f21bdd3e2a3c595",
                            "issuer_pem": "-----BEGIN CERTIFICATE-----\nMIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2xxxV2dlT0EpeNWbvuydrc6Xf6PL\n-----END RSA PRIVATE KEY-----\n",
                            "key_type": "2048",
                            "min_days_remaining": "7",
                            "must_staple": "false",
                            "private_key_pem": "",
                            "registration_url": "https://acme-v01.api.letsencrypt.org/acme/reg/21546469",
                            "server_url": "https://acme-v01.api.letsencrypt.org/directory",
                            "tls_challenge_port": "443"
                        },
                        "meta": {},
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": ""
                },

v1.0.0 - Change from ACME staging to prod

Hi,

I just updated your plugin from 0.50 to v1.0.0 and requested a new staging certificate. It worked perfectly with the documentation provided in https://github.com/vancluever/terraform-provider-acme/blob/v1.0.0/doc/resource_acme_certificate.md .

The issue occurred when changing from staging to prod, just by changing the variable server_url. The error was the following:

module.XXX.acme_registration.reg: acme_registration.reg: acme: Error 400 - urn:ietf:params:acme:error:accountDoesNotExist - No account exists with the provided key

I realised that by changing the server_url, the plugin was trying to get information about the existing account, created with the staging url, on the production url, and the production url had no information about the account.

I had to change the steps to the following:

# To force resource recreation, there are duplicate resources for each environment

# Create the private key for the registration
resource "tls_private_key" "reg_private_key_staging" {
  count     = "${var.acme_server_env == "staging" ? 1 : 0}"
  algorithm = "RSA"
  rsa_bits  = 4096

  lifecycle {
    create_before_destroy = true
  }
}

resource "tls_private_key" "reg_private_key_prod" {
  count     = "${var.acme_server_env == "prod" ? 1 : 0}"
  algorithm = "RSA"
  rsa_bits  = 4096

  lifecycle {
    create_before_destroy = true
  }
}

# Set up registration server
provider "acme" {
  alias      = "staging"
  server_url = "https://acme-staging-v02.api.letsencrypt.org/directory"
}

provider "acme" {
  alias      = "prod"
  server_url = "https://acme-v02.api.letsencrypt.org/directory"
}

# Set up a registration using a private key from tls_private_key
resource "acme_registration" "reg_staging" {
  count           = "${var.acme_server_env == "staging" ? 1 : 0}"
  provider        = "acme.staging"
  account_key_pem = "${tls_private_key.reg_private_key_staging.private_key_pem}"
  email_address   = "${var.email}"
}

resource "acme_registration" "reg_prod" {
  provider        = "acme.prod"
  count           = "${var.acme_server_env == "prod" ? 1 : 0}"
  account_key_pem = "${tls_private_key.reg_private_key_prod.private_key_pem}"
  email_address   = "${var.email}"
}

# Create the private key for the certificate
resource "tls_private_key" "cert_private_key_staging" {
  count     = "${var.acme_server_env == "staging" ? 1 : 0}"
  algorithm = "RSA"
  rsa_bits  = 4096

  lifecycle {
    create_before_destroy = true
  }
}

resource "tls_private_key" "cert_private_key_prod" {
  count     = "${var.acme_server_env == "prod" ? 1 : 0}"
  algorithm = "RSA"
  rsa_bits  = 4096

  lifecycle {
    create_before_destroy = true
  }
}

resource "tls_cert_request" "req_staging" {
  count           = "${var.acme_server_env == "staging" ? 1 : 0}"
  key_algorithm   = "RSA"
  private_key_pem = "${tls_private_key.cert_private_key_staging.private_key_pem}"
  dns_names       = ["${var.fqdn}"]

  subject {
    common_name = "${var.fqdn}"
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "tls_cert_request" "req_prod" {
  count           = "${var.acme_server_env == "prod" ? 1 : 0}"
  key_algorithm   = "RSA"
  private_key_pem = "${tls_private_key.cert_private_key_prod.private_key_pem}"
  dns_names       = ["${var.fqdn}"]

  subject {
    common_name = "${var.fqdn}"
  }

  lifecycle {
    create_before_destroy = true
  }
}

# Create a certificate.
resource "acme_certificate" "certificate_staging" {
  count                   = "${var.acme_server_env == "staging" ? 1 : 0}"
  provider                = "acme.staging"
  account_key_pem         = "${acme_registration.reg_staging.account_key_pem}"
  certificate_request_pem = "${tls_cert_request.req_staging.cert_request_pem}"
  min_days_remaining      = 7

  dns_challenge {
    provider = "route53"
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "acme_certificate" "certificate_prod" {
  count                   = "${var.acme_server_env == "prod" ? 1 : 0}"
  provider                = "acme.prod"
  account_key_pem         = "${acme_registration.reg_prod.account_key_pem}"
  certificate_request_pem = "${tls_cert_request.req_prod.cert_request_pem}"
  min_days_remaining      = 7

  dns_challenge {
    provider = "route53"
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_iam_server_certificate" "iam_server_certificate" {
  name_prefix = "${var.fqdn}-"

  certificate_body  = "${coalesce(join(",",acme_certificate.certificate_staging.*.certificate_pem),join(",",acme_certificate.certificate_prod.*.certificate_pem))}"
  certificate_chain = "${coalesce(join(",",acme_certificate.certificate_staging.*.issuer_pem),join(",",acme_certificate.certificate_prod.*.issuer_pem))}"
  private_key       = "${coalesce(join(",",tls_private_key.cert_private_key_staging.*.private_key_pem),join(",",tls_private_key.cert_private_key_prod.*.private_key_pem))}"
  path              = "/certs/"

  lifecycle {
    create_before_destroy = true
  }

  provisioner "local-exec" {
    command = "sleep 10"
  }
}

I'm sharing this to suggest that it would be best to reconfigure the plugin to keep the original server_url with the resource, or to upgrade the documentation with this information.

I can submit a pull request to the documentation if you want. Just let me know!

Keep up the great work :)

Regards
Gabriel

State migration smoke test

Just want to make sure that a state migration works:

  • Create a reg/cert using v0.6.0
  • Swap in the 1.0.0 provider
  • Validate that IDs have not changed on refresh
  • Crank min_days_remaining and renew cert

Remove HTTP and TLS challenges

HTTP and TLS challenges on a Terraform provider have never made sense to me, in retrospect - more than likely Terraform will be running on a machine that is not the webserver that will be receiving the certificate or the A record for any specific FQDN will be pointing to. Hence, in order for these challenges to work, they will usually need to be proxied from the target host, at least temporarily.

There is also the issue surrounding the current insecurity of TLS challenges.

In addition to the above, HTTP and TLS challenges are currently not a part of our standard testing routine as they require standing up other infrastructure and then running the acceptance tests on those hosts.

As part of our move to 1.0.0, these two challenges are (more than likely) going to be removed, with dns_challenge being the only remaining supported challenge method by the provider.

Publish your PGP Fingerprint

It is good that the releases are publish with SHA256 checksums and the checksum file is digitally signed using your PGP key. However we don't know what key should have signed the checksum file, if we knew what your keys fingerprint then we could extend trust from there.

> gpg --verify terraform-provider-acme_v1.0.0.SHA256SUMS.sig
gpg: assuming signed data in `terraform-provider-acme_v1.0.0.SHA256SUMS'
gpg: Signature made Mon Jun 18 06:44:16 2018 AUSEST using RSA key ID EC615CE4
gpg: Good signature from "Chris Marchesi <[email protected]>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 245C DB0E 5171 60F3 EBC5  6923 21DA 69C2 D14B FAA8
     Subkey fingerprint: CFED 9BDD 618A FC92 C28A  3CDA 335B 84AF EC61 5CE4

Requesting push access to/transfer of this repository

Hey PBP,

hashicorp/terraform#3599, was recently closed, and I expect a bit more traffic to be directed to the plugin now. As such, some maintenance may be required from time to time, especially now that the provider split has had time to settle.

Being that I have some personal attachment to the work here, I want to make sure that it continues to be maintained. With that, so that I can effectively help out with this project, I'm personally requesting (as myself, not in behalf of HashiCorp) either one of two things:

  • Push access to the repository and the ability to manage issues, etc.
  • Control of the project transferred to me (@vancluever), with endorsement that I can add to the copyright, with the new LICENSE looking like:
Copyright 2017 Chris Marchesi
Copyright 2016, 2017 PayByPhone Technologies, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

If someone can get back to me on this one, that would be great! Hope everyone is doing well.

Resource to generate a PKCS #12 archive file

Currently the ACME provider's resources are accessible as PEM outputs. It would be useful to be able to produce a PKCS #12 (PKCS12 or alternatively PFX) archive format file out of these components, as there are cases where a PFX archive is preferred or even required.

I recommend supporting this resource in a more general-purpose manner, such that you can give it an optional private key PEM, and one or more certificates (i.e. an array of certificate PEM clobs). By doing so, the resource would be usable in tandem with other resources of this provider, as well as alternate providers, such as the out-of-the-box TLS provider.

Note, I have a similar request out in terraform-provider-tls/#29 because I do feel it is more natural and general-purpose for that provider to implement this resource, however, I'm not sure how likely the are to produce it in a timely manner.

Remove OCSP post-revocation validation

This is currently causing a number of issues, as documented in #30 and #32. It is also causing a number of problems during testing as well, and is generally unreliable.

As part of 1.0.0, we will be removing the post-revocation validation and just rely on RevokeCertificate to do revocation. If need be, we can eventually re-add it, where it will more than likely be optional and disabled by default.

ACME plugin generates 403 GoogleCloud API permissions error attempting to update GCS-based Terraform state

We've been using the paybyphone ACME plugin for Terraform for just shy of a year and it mostly works great....except when we run it in a container. For some reason the plugin works fine for us locally, but fails to be able to write to the Google Cloud Storage-based state when in a container. What's odd is that all other resources native to Terraform work fine, but anything using the ACME plugin fails with a 403 GoogleCloud API error:

2017-12-09T00:27:21.283Z [DEBUG] plugin.terraform-provider-acme: 2017/12/09 00:27:21 [INFO][api-ext.prod.***.co] acme: Could not find
2017-12-09T00:27:21.283Z [DEBUG] plugin.terraform-provider-acme: 2017/12/09 00:27:21 [INFO][api-ext.prod.***.co] acme: Trying to solv
2017/12/09 00:27:21 [ERROR] root: eval: *terraform.EvalApplyPost, err: 1 error(s) occurred:

* acme_certificate.apiext_ssl_certificate: Error presenting token: GoogleCloud API call failed: googleapi: Error 403: Insufficient Permission,
2017/12/09 00:27:21 [ERROR] root: eval: *terraform.EvalSequence, err: 1 error(s) occurred:

* acme_certificate.apiext_ssl_certificate: Error presenting token: GoogleCloud API call failed: googleapi: Error 403: Insufficient Permission,
2017/12/09 00:27:21 [TRACE] [walkApply] Exiting eval tree: acme_certificate.apiext_ssl_certificate
2017/12/09 00:27:21 [INFO] Writing tf-state-prod/terraform/terraform.tfstate
Error applying plan:

2 error(s) occurred:

* acme_certificate.apiint_ssl_certificate: 1 error(s) occurred:

* acme_certificate.apiint_ssl_certificate: Error presenting token: GoogleCloud API call failed: googleapi: Error 403: Insufficient Permission,
2017/12/09 00:27:21 [DEBUG] plugin: waiting for all plugin processes to complete...
* acme_certificate.apiext_ssl_certificate: 1 error(s) occurred:

* acme_certificate.apiext_ssl_certificate: Error presenting token: GoogleCloud API call failed: googleapi: Error 403: Insufficient Permission,

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

Because Terraform is able to write to the state just fine for all other native resources, and because the ACME plugin isn't giving debug output, I can't tell what user it's trying to use (maybe different from what Terraform is trying to use natively?) to write to the state which results in a 403. In any case, I've ensured that both the service account I've told Terraform to use, and the service account that the GKE cluster gets by default, have read/write access to the storage bucket that contains the Terraform state.

Why would Terraform be able to write to the state, but ACME plugin not?

is it compatible with terraform v.0.7.13?

# Create the private key for the registration (not the certificate)
resource "tls_private_key" "private_key" {
  algorithm = "RSA"
}

# Set up a registration using a private key from tls_private_key
resource "acme_registration" "reg" {
  server_url      = "https://acme-v01.api.letsencrypt.org/directory"
  account_key_pem = "${tls_private_key.private_key.private_key_pem}"
  email_address   = "[email protected]"
}

# Create a certificate
resource "acme_certificate" "certificate" {
  server_url                = "https://acme-v01.api.letsencrypt.org/directory"
  account_key_pem           = "${tls_private_key.private_key.private_key_pem}"
  common_name               = "example.com"
  subject_alternative_names = ["s3.example.com"]

  dns_challenge {
    provider = "route53"
    config {
      AWS_ACCESS_KEY_ID     = "${var.aws_access_key_id}"
      AWS_SECRET_ACCESS_KEY = "${var.aws_access_key}"
      AWS_DEFAULT_REGION    = "us-east-1"
    }
  }
  registration_url = "${acme_registration.reg.id}"
}

resource "aws_iam_server_certificate" "some_cert" {
  name = "some_cert"
  certificate_body = "${acme_certificate.certificate.certificate_pem}"
  private_key = "${acme_certificate.certificate.private_key_pem}"
}

and I get this:

2016/12/08 00:49:25 [DEBUG] plugin: waiting for all plugin processes to complete...
Error configuring: 1 error(s) occurred:

* fork/exec /Users/deman/bin/terraform-provider-acme: exec format error
2016/12/08 00:49:25 [DEBUG] plugin: /usr/local/Cellar/terraform/0.7.13/bin/terraform: plugin process exited
2016/12/08 00:49:25 [DEBUG] plugin: /usr/local/Cellar/terraform/0.7.13/bin/terraform: plugin process exited
2016/12/08 00:49:25 [DEBUG] plugin: /usr/local/Cellar/terraform/0.7.13/bin/terraform: plugin process exited

resource/certificate: ID should change on renewal

In #48 we restored the URL attributes to both resources and ensured that ID modification was de-coupled from the resource lifecycle aside from create.

I would like to modify this for acme_certificate as technically, in lego, a renewal is an entirely new certificate. I don't know if this is an ACME or lego shortcoming, but it doesn't necessarily matter as we mainly care about how it's currently implemented in the client.

As such, we should do a d.SetId with the new certificate URL upon renewal. We can also toss a check into TestAccACMECertificate_forceRenewal to make sure the ID is stable upon both creation and renewal.

top domain is not managed by current aws account

If root domain (example.com) is managed by different providers. We manage the subdomain as dev.example.com in current aws account.

But when use the sample to create a new certificate, I got below error:

* acme_certificate.certificate: Errors were encountered creating the certificate:
    abc.dev.example.com: Error presenting token: Failed to determine Route 53 hosted zone ID: Zone example.com. not found in Route 53 for domain _acme-challenge.abc.dev.example.com.

So can I define the hosted zone ID directly?

Certificate and Private Key Mismatch

Hi there!

I've just been trying out this plugin as I've been looking for a way to automate applying "Lets Encrypt" certificates to an AWS CloudFront resource. Thing seemed to be going well, and I was getting a cert from the ACME provider, but then I try to upload it to AWS

resource "aws_iam_server_certificate" "some_cert" {
  name = "some_cert"
  certificate_body = "${acme_certificate.certificate.certificate_pem}"
  private_key = "${tls_private_key.private_key.private_key_pem}"
}

At this point amazon informed me that there was a mismatched. I created a couple of outlets in terraform to get a copy of the cert and key, and double confirmed the cert and key don't match using openssl.

I'm not sure if it's a problem with my setup, or maybe there's something going on in the plugin.

My setup, aside from some naming, is pretty much the same setup as your first example. If there's a better place to put this, please let me know.

Thanks!

Error 429 - urn:acme:error:rateLimited - Error creating new cert :: too many certificates already issued for exact set of domains

I did some tweaking on my Terraform config yesterday and wanted to continue today. As I issued the first terraform plan it failed with the error in the subject.
I am aware of this rate limit, I checked my domain on https://crt.sh, and it shows that I have requested certs for the exact same domains 5 times within a day.
What I do not understand is that the first request was at Nov 29 ~09:45 2017 GMT. According to my knowledge I renewed my cert sometime around Nov 30 01:30-03:00 2017 GMT.

Why are there these cert requests?
Is there any workaround or I MUST wait 7 days? Actually this does not cause any real issues (yet), it is just annoying I cannot do terraform plan (only terraform plan --target=any_resource_but_acme_cert). In theory changing the SAN list (as I am using a few already) would result a different set of domains, so it won't be affected by the rate limit. I already tried it, added a new name to the SANs (actually I wanted to add it a week ago, but I forgot), but as I do a terraform plan --target=acme_cert --out=tf.o it fails with the same error, and the new SAN is not in the "exact set of domains".
I guess it fails already during the refresh but I cannot understand why it does not pick up the updated SAN list.

acme_registration: Now manages "accounts"

The ACME v2 protocol and current spec no longer defines accounts as "registrations". API-wise this has not had too many implications with how clients deal with lego, but may cause some confusion to new users of the provider.

I don't have any plans to change this for version 1.0.0, as I want people to be able to carry forward v1 registrations (which is supported). However, we should document this to avoid any confusion.

Question/docs: lifecycle for created acme_certificate resources?

Once certificates are created via a resource "acme_certificate" ... block, what happens next?

  • Could you add an example of deploying (and renewing?) a cert to e.g. an aws_instance? Or is this just the file provider and a lot of elbow grease?
  • Are there any concerns about the (sensitive) contents of private_key_pem being persisted to tfstate?

Thanks!

Reorganize code, update/remove old documentation

As part of 1.0.0 I want to update the code to be a bit more in line with current TF provider convention. This means that the provider should be in a simple acme package off of the source root.

Also, I would like to update the README so that we have removed mention of the old PR, given that it's been about 3 years since the PR was put in, it's kind of old news.

Finally, we can remove the documentation in website for now. If there is ever a time that this is upstreamed, we can re-add the docs in the format of the rest of the post-provider-split providers.

not compatible with terraform 0.8

โฏ terraform plan
Error configuring: 1 error(s) occurred:

* Incompatible API version with plugin. Plugin version: 1, Ours: 2

acme_registration <-> acme_certificate resource relationship

Due to the changes in both ACME spec and the lego API, an ACME registration/account is now a very small resource, consisting of mainly only the ID. All other fields are ultimately superfluous - registration body is a field, but is currently not exported, and registration URL will change from the transition from ACME v1 to v2, more than likely causing issues with existing certificates as the URL change would force a new resource.

As a result, we are dropping all unique fields from acme_registration, save email_address. registration_url will also be dropped from acme_certificate.

The new relationship will be based off of private key, and should follow the following convention, to ensure proper resource precedence:

resource "acme_registration" "reg" {
  ...
  private_key_pem = "KEY"
}

resource "acme_certificate" "cert" {
  ...
  private_key_pem = "${acme_registration.reg.private_key_pem}"
}

Cannot use AWS_SDK_LOAD_CONFIG and AWS_PROFILE in route53 config

Hi,

I've tried to use AWS_SDK_LOAD_CONFIG: "1" and AWS_PROFILE="myprofile" in the config {} section for route53, without success. I've traced it to a usage of a deprecated session.New in lego, and submitted a PR there: go-acme/lego#528 , issue: go-acme/lego#458

I've locally applied the patch to the vendored lego, and it fixes the issue for me.

It would be great if the fix could make it into 0.6 if possible.

Cheers,
Johannes

Specify Route53 Zone ID

I'm using a private hosted zone in Route 53 and I'm getting the following error eventhough the zone exists:

develop-env1.cj.uat.dev.mycompany.com: Error presenting token: Failed to determine Route 53 hosted zone ID:
Zone mycompany.com

Is it possible to specify the ZoneID? is it possible to use a private hosted zone?

reg/cert: Ensure IDs don't change, restore resource URL attributes

It dawned on me that I'm not entirely too comfortable with the idea of changing IDs on Terraform resources. These things should not change during the lifecycle of a resource.

I'm not 100% too sure of the implications (to know, I'd probably need to ask someone or do a dive into the code), but it's relatively easy enough to set things up in the ACME provider so that we don't rely on the ID for things like up to date registration and certificate URLs.

Basically what I want to do is:

  • Restore the registration_url on acme_registration, and certificate_url on acme_certificate.
  • registration_url will not be restored on acme_certificate, as we still want the dependency on the private key, as fetching this from the API will always work and is how we refresh reg data in acme_registration.
  • Ensure any flatteners or expanders don't touch or depend on the ID of the respective resource.
  • Set the ID once during resource creation, and leave it alone for the rest of the lifecycle (unless a resource needs to be flagged for re-creation during refresh).

Terraform Provider Development Program

Hey Chris ๐Ÿ‘‹

I went through the repo and found a few items we should address before merging the provider into terraform-repostories/ org.

  • Is the 'doc' directory necessary, looks like its just the doc pages for the provider's resources. Can it be removed?

  • Do you plan on create a examples/ dir with example terraform configs?

  • The repo currently have a Apache license, the standard for all Terraform providers is a MPL2 license, could you update that?

  • The Makefile is not aligned with the standard GNUmakefile used across Terraform provider. You'll need to make sure that the tasks in your makefile align the standard tasks.

We can talk more about this tomorrow. :)

import the certificate to aws certificate manager

@vancluever

If you don't have write permission for current repo, we can work on your fork first. It is normal.

I put a comment in Hashicorp Terraform (hashicorp/terraform#4782 (comment) )

But I think this should be implemented in provider terraform-provider-acme, more than in terraform core service or terraform provider aws.

So after I get the free certificate from this provder, I need a new resource to import it to aws certificate manager, something as:

resource "acme_import_to_acm" {
  certificate = "${acme_certificate.certificate.certificate_pem}"
  certificate-chain = "${acme_certificate.certificate.issuer_pem}"
  private-key = "${acme_certificate.certificate.private_key_pem}"
}

or directly add a new argument in resource acme_certificate

resource "acme_certificate" "certificate" {
  server_url       = "https://acme-staging.api.letsencrypt.org/directory"
  account_key_pem  = "${tls_private_key.reg_private_key.private_key_pem}"
  certificate_request_pem = "${tls_cert_request.req.cert_request_pem}"

  dns_challenge {
    provider = "route53"
  }

  import = "aws"   # [aws|gce|azure|...]
  ...
}

Can you help?

And need support reimport as well to easily renew the certificate.

Any suggestions to work around with terraform if i don't have this feature currently?

One more tip. When I manually import the PEMs, I need to remove all "\n" first, otherwise, AWS will report problem.

Support for manual DNS challenge handler

Is it possible to add support for a manual challenge handler for a DNS challenge?

The lego library already has support for it, and it would an "escape hatch" to possibly support any DNS provider, not just the ones that are first-class supported by lego?

I know the design of the current dns_challenge mechanism makes this a little difficult because it's currently all self-contained and supporting a manual challenge would essentially require a 2-part approach (generate the challenge response details, then submit the challenge response), but I think it's doable.

Migration from dns_challenge config to environment variables config stuck in state

Previously I had a config like this: -

resource "acme_certificate" "docs-pub" {
   dns_challenge {
     provider = "azure"
    config {
      AZURE_SUBSCRIPTION_ID = "${var.arm_subscription_id}"
      AZURE_CLIENT_ID       = "${var.arm_client_id}"
      AZURE_CLIENT_SECRET   = "${var.arm_client_secret}"
      AZURE_TENANT_ID       = "${var.arm_tenant_id}"
      AZURE_RESOURCE_GROUP  = "${var.dns_zone_rg_name}"
    }
}

And I removed the AZURE_* properties so that credentials must be passed in the environment variables: AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, AZURE_RESOURCE_GROUP.

After do terraform plan and terraform apply the execution plan always wants to remove the old AZURE_* properties but they are stuck, after an apply they are still in the state and a subsequent apply will have the same execution plan.

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ module.docs-elttam.acme_certificate.docs-pub
      dns_challenge.2546575925.provider:                     "" => "azure"
      dns_challenge.3392271354.config.%:                     "5" => "0"
      dns_challenge.3392271354.config.AZURE_CLIENT_ID:       "<REDACTED>" => ""
      dns_challenge.3392271354.config.AZURE_CLIENT_SECRET:   "<REDACTED>" => ""
      dns_challenge.3392271354.config.AZURE_RESOURCE_GROUP:  "<REDACTED>" => ""
      dns_challenge.3392271354.config.AZURE_SUBSCRIPTION_ID: "<REDACTED>" => ""
      dns_challenge.3392271354.config.AZURE_TENANT_ID:       "<REDACTED>" => ""
      dns_challenge.3392271354.provider:                     "azure" => ""

I'd like the old configuration properties to be removed by the apply and a subsequent apply to say no changes required. I'm not sure how to manually clear the issue, if I manually remove the state I'm not sure if it's possible to import the certificate and keys etc.

Terraform / ACME version

Terraform v0.11.7
+ provider.acme v1.0.0
+ provider.azurerm v1.8.0bc
+ provider.local v1.1.0
+ provider.null v1.0.0
+ provider.random v1.3.1
+ provider.tls v1.1.0

Plugin usage on Terraform Enterprise

The problem I had attempting to use a "provider" block with versions prior to v1.0.0 is not documented. The doc does recommend version 0.6.0 if ACME v1 is needed, so it should also make a note similar to: "Omit the provider block if using version 0.6.0."

Allow for registration deletion

Looks like registration deletion was added to Boulder sometime in 2016.

There is currently unused functionality in the ACME provider that helps fetch registrations, a pull-in of the new lego code helped to bubble this to the surface as the API has changed enough to cause the code to break. Let's fix it and allow registrations to be deleted.

Also, it might be worthwhile to add the necessary code to lego to update contacts in a registration as well, which also seems possible now.

provider.acme.server_url change not forcing a new resource

I migrated over to terraform-provider-acme v1.0.0 just now, with the new protocol. Obviously, I tested with provider.acme.server_url = "https://acme-staging-v02.api.letsencrypt.org/directory" while I made sure everything worked (it did - awesome job!)

But then when I wanted to get a prod certificate, and I switched to provider.acme.server_url = "https://acme-v02.api.letsencrypt.org/directory" and ran terraform plan, and it detected no changes. Obviously I was expecting it to re-issue a certificate against the new server_url, even though the existing staging one is "valid".

I know I can force a new resource, but this seems like a bug worth reporting. Thanks again for this excellent resource!

Latest release breaks under Alpine

Is there a reason as to why the latest release (0.5.0) is dynamically linked instead of statically? It breaks Alpine compatibility:

# 0.5.0
/ # file /root/.terraform.d/plugins/terraform-provider-acme 
/root/.terraform.d/plugins/terraform-provider-acme: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, with debug_info, not stripped

# 0.4.0
/ # file /root/.terraform.d/plugins/terraform-provider-acme 
/root/.terraform.d/plugins/terraform-provider-acme: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped

I know this isn't necessarily a target platform, but it looks like unwanted side-effect to me .. ?

Alpine version used is 3.7.0 (stable).

DNS Challenge does not disable HTTPS server

Hi,

Unless I am doing something wrong (please do correct me if I am) I am trying to configure my setup to do a DNS challenge, however I get an error when I run it saying that it can't start an HTTP/S server which I believe should not be the case, and should instead be disabled?

This is the error I am getting:

Error applying plan:

1 error(s) occurred:

* acme_certificate.certificate: Errors were encountered creating the certificate:
    example.com: [example.com] error presenting token: Could not start HTTP server for challenge -> listen tcp :80: bind: permission denied
    test.example.com: [test.example.com] error presenting token: Could not start HTTPS server for challenge -> listen tcp :443: bind: permission denied

This is what my terraform certificate resource looks like:

# Create a certificate
resource "acme_certificate" "certificate" {
  server_url                = "https://acme-staging.api.letsencrypt.org/directory"
  account_key_pem           = "${data.terraform_remote_state.letsencrypt_registration.letsencrypt-registration-privkey}"
    common_name               = "example.com"
  subject_alternative_names = ["test.example.com"]


  dns_challenge {
    provider = "dnsimple"
  }

  registration_url = "${data.terraform_remote_state.letsencrypt_registration.letsencrypt-registration-id}"
}

So not sure if this is a bug, or I have done something else wrong?
Thanks!

Error 409 - urn:acme:error:malformed - Certificate already revoked

In my certificates I have create_before_destroy set in the lifecycle settings. I do this because I always want a valid certificate to be active, if this isn't set then the cert is destroyed and then a new one created, which leaves a few mins with no active certificates.

During the destroy process it timed out, which has left a deposed resource in my state file. When I try to do a plan it comes it as a destroy operation:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  - acme_certificate.jumplead-io (deposed)


Plan: 0 to add, 0 to change, 1 to destroy.

But when applying this plan it fails because the certificate has already been removed:

acme_certificate.jumplead-io.deposed: Destroying... (ID: https://acme-v01.api.letsencrypt.org/ac...t/048b267ca05e8031828b905109e0b4a7f8b6)

Error: Error applying plan:

1 error(s) occurred:

* acme_certificate.jumplead-io (destroy): 1 error(s) occurred:

* acme_certificate.jumplead-io (deposed #0): 1 error(s) occurred:

* acme_certificate.jumplead-io (deposed #0): acme: Error 409 - urn:acme:error:malformed - Certificate already revoked

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

This has currently left me with a broken state file as I'm unable to apply the destroy. Would it be possible if a 409 status has been returned to carry on with the normal terraform function?

Incompatible API version with plugin error

I'm using:

Terraform v0.8.6 and have tried as well Terraform v0.8.0 however I'm getting the following error:

Error configuring: 1 error(s) occurred:

* Incompatible API version with plugin. Plugin version: 3, Ours: 2

The last bit it's confusing version: 3, Ours: 2 ? sound's like the plugin version it's newer than the version on my local Terraform the opposite of what's going on in this closed issue #5

Any idea why this could be happening?

btw I used brew to install go and I'm on mac (El Capitan)

Thanks,

acme_registration.registration fails to get https://acme-v01.api.letsencrypt.org/directory

I am currently running into this error when I use the ACME terraform plugin

2017/05/02 10:15:49 [ERROR] root: eval: *terraform.EvalApplyPost, err: 1 error(s) occurred:    

 acme_registration.registration: get directory at 'https://acme-v01.api.letsencrypt.org/directory': 
  failed to get "https://acme-v01.api.letsencrypt.org/directory": Get https://acme- 
  v01.api.letsencrypt.org/directory: net/http: request canceled while waiting for connection    
 (Client.Timeout exceeded while awaiting headers)    
2017/05/02 10:15:49 [ERROR] root: eval: *terraform.EvalSequence, err: 1 error(s) occurred:    

 acme_registration.registration: get directory at 'https://acme-v01.api.letsencrypt.org/directory':       
   failed to get "https://acme-v01.api.letsencrypt.org/directory": Get https://acme- 
  v01.api.letsencrypt.org/directory: net/http: request canceled while waiting for connection  
  (Client.Timeout exceeded while awaiting headers)   
Error applying plan:   

1 error(s) occurred:   

* acme_registration.registration: get directory at 'https://acme-v01.api.letsencrypt.org/directory':    failed to get "https://acme-v01.api.letsencrypt.org/directory": Get https://acme-     
  v01.api.letsencrypt.org/directory: net/http: request canceled while waiting for connection    (Client.Timeout exceeded while awaiting headers)    

this is what I get when I curl

 curl https://acme-v01.api.letsencrypt.org/directory
{
  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",
  "new-authz": "https://acme-v01.api.letsencrypt.org/acme/new-authz",
  "new-cert": "https://acme-v01.api.letsencrypt.org/acme/new-cert",
  "new-reg": "https://acme-v01.api.letsencrypt.org/acme/new-reg",
  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"
}% 

The plugin seems to be working for other people in the same cidr block.
I am using v0.2.1 with Terraform 0.8.8

Route53 provider timeout

๐Ÿ‘‹ Hey @vancluever, I'm not sure if this is an issue with the provider or xenolf/lego but it would be good to be able to configure timeouts for the provider.

When creating a certificate with route53 I hit a timeout on the first run

acme_certificate.certificate: Still creating... (3m30s elapsed)
acme_certificate.certificate: Still creating... (3m40s elapsed)
acme_certificate.certificate: Still creating... (3m50s elapsed)
acme_certificate.certificate: Still creating... (4m0s elapsed)
acme_certificate.certificate: Still creating... (4m10s elapsed)
acme_certificate.certificate: Still creating... (4m20s elapsed)

Error: Error applying plan:

1 error(s) occurred:

* acme_certificate.certificate: 1 error(s) occurred:

* acme_certificate.certificate: error creating certificate: acme: Error -> One or more domains had a problem:
[*********] Time limit exceeded. Last error: NS ns-71.awsdns-2.net. did not return the expected TXT record


Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
```

acme_registration: State migration

State has changed for acme_registration (removed fields) but these should be removed from the state of the resource as well so that unused fields are not persisted in state post-migration.

ACME v2

The ACME v2 protocol now has a staging server. It would be awesome if we could start looking at how this might affect this plugin. The main benefit of v2 is the ability to issue wildcards :)

Having trouble behind corporate proxy

Hi,

there seems to be a problem, when I run behind a corporate proxy.

situation:

  • terraform
  • AWS
  • I can setup my AWS environment with terraform
  • environment variables regarding proxy are set: HTTP_PROXY, HTTPS_PROXY, NO_PROXY

error message:


1 error(s) occurred:

* acme_registration.reg: 1 error(s) occurred:

* acme_registration.reg: get directory at 'https://acme-staging.api.letsencrypt.org/directory': failed to get json "https://acme-staging.api.letsencrypt.org/directory": Get https://acme-staging.api.letsencrypt.org/directory: dial tcp 104.12
5.70.118:443: connectex: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat.

Terraform does not automatically rollback in the face of errors.

some research:

var HTTPClient = http.Client{

 Transport: &http.Transport{
 Proxy: http.ProxyFromEnvironment,
 Dial: (&net.Dialer{

question:

  • Maybe there could be an issue with passing the environment to lego?

Cheers,
Tobias.

ACME provider does trigger cert renewal/replacement despite being below min_days_remaining

I deployed all of my virtual infrastructure over the past few months with Terraform, and pulled in your awesome ACME plugin for managing SSL certs (thanks by the way!).

Today it's almost been 90 days so it's the first time I went to renew the certs. I have min_days_remaining for my certs set to 7 days, so I figured if I just ran terraform apply on my current state, it would realize my cert(s) were less than 7 days from renewal and kick in. Unfortunately it didn't. Here's my related config:

// Create the private key for the registration (not the certificate)
resource "tls_private_key" "letsencrypt_private_key" {
  algorithm          = "RSA"
  rsa_bits           = "2048"
}

// Set up a registration using a private key from tls_private_key
resource "acme_registration" "reg" {
  server_url         = "https://acme-v01.api.letsencrypt.org/directory"
  account_key_pem    = "${tls_private_key.letsencrypt_private_key.private_key_pem}"
  email_address      = "ops@${var.ORG}.${var.TLD}"
}

/////////////// Begin api.(env).(org).(tld) SSL setup /////////////
// Create the private key for the API certificate
resource "tls_private_key" "api_ssl_private_key" {
  algorithm          = "RSA"
  rsa_bits           = "2048"
}

// GCP Output for above SSL private key
output "api_ssl_private_key" {
  value              = "${tls_private_key.api_ssl_private_key.private_key_pem}"
}

resource "tls_cert_request" "api_ssl_req" {
  key_algorithm      = "RSA"
  private_key_pem    = "${tls_private_key.api_ssl_private_key.private_key_pem}"
//  dns_names        = ["www.example.com", "www2.example.com"]

  subject {
    common_name      = "api.${var.ENV_SHORT}.${var.ORG}.${var.TLD}"
  }
}

// Create a certificate
resource "acme_certificate" "api_ssl_certificate" {
  depends_on         = ["google_dns_managed_zone.env-org-tld"]
  server_url         = "https://acme-v01.api.letsencrypt.org/directory"
  account_key_pem    = "${tls_private_key.letsencrypt_private_key.private_key_pem}"
  certificate_request_pem  = "${tls_cert_request.api_ssl_req.cert_request_pem}"
  min_days_remaining = "7"

  dns_challenge {
    provider = "gcloud"
    config {
      GCE_PROJECT    = "${var.ORG}-${var.ENV_SHORT}"
      GCE_DOMAIN     = "${var.ENV_SHORT}.${var.ORG}.${var.TLD}"
    }
  }

  registration_url   = "${acme_registration.reg.id}"
}

output "api_ssl_certificate" {
  value              = "${acme_certificate.api_ssl_certificate.certificate_pem}"
}

output "api_ssl_intermediate" {
  value              = "${acme_certificate.api_ssl_certificate.issuer_pem}"
}
/////////////// End api.(env).(org).(tld) SSL setup /////////////

Note that I did find a simple workaround that's due to #13 - I simply dropped min_days_remaining to 6 and re-ran terraform apply and that got the job done. I have a feeling that bug will eventually be fixed though =)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.