Skip to content

Commit 804d714

Browse files
Restore tls_cert_request to being a managed resource
In c244e5a this resource was converted to a data source, but that was a mistake since data sources are expected to produce stable results on each run, and yet certificate requests contain a random nonce as part of the signature. Additionally, using the data source as a managed resource through the provided compatibility shim was not actually working, since "Read" was trying to parse the private key out of a SHA1 hash of the key, which is what we place in state due to the StateFunc on that attribute. By restoring this we restore Terraform's ability to produce all of the parts of a basic PKI/CA, which is useful for creating dev environments and bootstrapping PKI for production environments.
1 parent 7d2b51e commit 804d714

5 files changed

Lines changed: 37 additions & 24 deletions

File tree

builtin/providers/tls/provider.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,11 @@ import (
1212

1313
func Provider() terraform.ResourceProvider {
1414
return &schema.Provider{
15-
DataSourcesMap: map[string]*schema.Resource{
16-
"tls_cert_request": dataSourceCertRequest(),
17-
},
1815
ResourcesMap: map[string]*schema.Resource{
1916
"tls_private_key": resourcePrivateKey(),
2017
"tls_locally_signed_cert": resourceLocallySignedCert(),
2118
"tls_self_signed_cert": resourceSelfSignedCert(),
22-
23-
"tls_cert_request": schema.DataSourceResourceShim(
24-
"tls_cert_request",
25-
dataSourceCertRequest(),
26-
),
19+
"tls_cert_request": resourceCertRequest(),
2720
},
2821
}
2922
}

builtin/providers/tls/data_source_cert_request.go renamed to builtin/providers/tls/resource_cert_request.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ import (
1212

1313
const pemCertReqType = "CERTIFICATE REQUEST"
1414

15-
func dataSourceCertRequest() *schema.Resource {
15+
func resourceCertRequest() *schema.Resource {
1616
return &schema.Resource{
17-
Read: ReadCertRequest,
17+
Create: CreateCertRequest,
18+
Delete: DeleteCertRequest,
19+
Read: ReadCertRequest,
1820

1921
Schema: map[string]*schema.Schema{
2022

2123
"dns_names": &schema.Schema{
2224
Type: schema.TypeList,
2325
Optional: true,
2426
Description: "List of DNS names to use as subjects of the certificate",
27+
ForceNew: true,
2528
Elem: &schema.Schema{
2629
Type: schema.TypeString,
2730
},
@@ -31,6 +34,7 @@ func dataSourceCertRequest() *schema.Resource {
3134
Type: schema.TypeList,
3235
Optional: true,
3336
Description: "List of IP addresses to use as subjects of the certificate",
37+
ForceNew: true,
3438
Elem: &schema.Schema{
3539
Type: schema.TypeString,
3640
},
@@ -40,12 +44,14 @@ func dataSourceCertRequest() *schema.Resource {
4044
Type: schema.TypeString,
4145
Required: true,
4246
Description: "Name of the algorithm to use to generate the certificate's private key",
47+
ForceNew: true,
4348
},
4449

4550
"private_key_pem": &schema.Schema{
4651
Type: schema.TypeString,
4752
Required: true,
4853
Description: "PEM-encoded private key that the certificate will belong to",
54+
ForceNew: true,
4955
StateFunc: func(v interface{}) string {
5056
return hashForState(v.(string))
5157
},
@@ -55,6 +61,7 @@ func dataSourceCertRequest() *schema.Resource {
5561
Type: schema.TypeList,
5662
Required: true,
5763
Elem: nameSchema,
64+
ForceNew: true,
5865
},
5966

6067
"cert_request_pem": &schema.Schema{
@@ -65,7 +72,7 @@ func dataSourceCertRequest() *schema.Resource {
6572
}
6673
}
6774

68-
func ReadCertRequest(d *schema.ResourceData, meta interface{}) error {
75+
func CreateCertRequest(d *schema.ResourceData, meta interface{}) error {
6976
key, err := parsePrivateKey(d, "private_key_pem", "key_algorithm")
7077
if err != nil {
7178
return err
@@ -109,3 +116,12 @@ func ReadCertRequest(d *schema.ResourceData, meta interface{}) error {
109116

110117
return nil
111118
}
119+
120+
func DeleteCertRequest(d *schema.ResourceData, meta interface{}) error {
121+
d.SetId("")
122+
return nil
123+
}
124+
125+
func ReadCertRequest(d *schema.ResourceData, meta interface{}) error {
126+
return nil
127+
}

builtin/providers/tls/data_source_cert_request_test.go renamed to builtin/providers/tls/resource_cert_request_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ import (
1212
)
1313

1414
func TestCertRequest(t *testing.T) {
15-
r.UnitTest(t, r.TestCase{
15+
r.Test(t, r.TestCase{
1616
Providers: testProviders,
1717
Steps: []r.TestStep{
1818
r.TestStep{
1919
Config: fmt.Sprintf(`
20-
data "tls_cert_request" "test" {
20+
resource "tls_cert_request" "test" {
2121
subject {
2222
common_name = "example.com"
2323
organization = "Example, Inc"
@@ -46,7 +46,7 @@ func TestCertRequest(t *testing.T) {
4646
EOT
4747
}
4848
output "key_pem" {
49-
value = "${data.tls_cert_request.test.cert_request_pem}"
49+
value = "${tls_cert_request.test.cert_request_pem}"
5050
}
5151
`, testPrivateKey),
5252
Check: func(s *terraform.State) error {

website/source/docs/providers/tls/d/cert_request.html.md renamed to website/source/docs/providers/tls/r/cert_request.html.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,21 @@ typical format used to request a certificate from a certificate authority.
1313

1414
This resource is intended to be used in conjunction with a Terraform provider
1515
for a particular certificate authority in order to provision a new certificate.
16+
This is a *logical resource*, so it contributes only to the current Terraform
17+
state and does not create any external managed resources.
18+
19+
~> **Compatibility Note** From Terraform 0.7.0 to 0.7.4 this resource was
20+
converted to a data source, and the resource form of it was deprecated. This
21+
turned out to be a design error since a cert request includes a random number
22+
in the form of the signature nonce, and so the data source form of this
23+
resource caused non-convergent configuration. The data source form is no longer
24+
supported as of Terraform 0.7.5 and any users should return to using the
25+
resource form.
1626

1727
## Example Usage
1828

1929
```
20-
data "tls_cert_request" "example" {
30+
resource "tls_cert_request" "example" {
2131
key_algorithm = "ECDSA"
2232
private_key_pem = "${file(\"private_key.pem\")}"
2333

website/source/layouts/tls.erb

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@
1010
<a href="/docs/providers/tls/index.html">TLS Provider</a>
1111
</li>
1212

13-
<li<%= sidebar_current(/^docs-tls-data-source/) %>>
14-
<a href="#">Data Sources</a>
15-
<ul class="nav nav-visible">
16-
<li<%= sidebar_current("docs-tls-data-source-cert-request") %>>
17-
<a href="/docs/providers/tls/d/cert_request.html">tls_cert_request</a>
18-
</li>
19-
</ul>
20-
</li>
21-
2213
<li<%= sidebar_current(/^docs-tls-resource/) %>>
2314
<a href="#">Resources</a>
2415
<ul class="nav nav-visible">
@@ -31,6 +22,9 @@
3122
<li<%= sidebar_current("docs-tls-resource-locally-signed-cert") %>>
3223
<a href="/docs/providers/tls/r/locally_signed_cert.html">tls_locally_signed_cert</a>
3324
</li>
25+
<li<%= sidebar_current("docs-tls-resourse-cert-request") %>>
26+
<a href="/docs/providers/tls/r/cert_request.html">tls_cert_request</a>
27+
</li>
3428
</ul>
3529
</li>
3630
</ul>

0 commit comments

Comments
 (0)