forked from hashicorp/terraform-provider-aws
-
Notifications
You must be signed in to change notification settings - Fork 0
/
resource_aws_acm_certificate_validation.go
142 lines (115 loc) · 4.41 KB
/
resource_aws_acm_certificate_validation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package aws
import (
"fmt"
"log"
"reflect"
"sort"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/acm"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceAwsAcmCertificateValidation() *schema.Resource {
return &schema.Resource{
Create: resourceAwsAcmCertificateValidationCreate,
Read: resourceAwsAcmCertificateValidationRead,
Delete: resourceAwsAcmCertificateValidationDelete,
Schema: map[string]*schema.Schema{
"certificate_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"validation_record_fqdns": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(45 * time.Minute),
},
}
}
func resourceAwsAcmCertificateValidationCreate(d *schema.ResourceData, meta interface{}) error {
certificate_arn := d.Get("certificate_arn").(string)
acmconn := meta.(*AWSClient).acmconn
params := &acm.DescribeCertificateInput{
CertificateArn: aws.String(certificate_arn),
}
resp, err := acmconn.DescribeCertificate(params)
if err != nil {
return fmt.Errorf("Error describing certificate: %s", err)
}
if *resp.Certificate.Type != "AMAZON_ISSUED" {
return fmt.Errorf("Certificate %s has type %s, no validation necessary", *resp.Certificate.CertificateArn, *resp.Certificate.Type)
}
if validation_record_fqdns, ok := d.GetOk("validation_record_fqdns"); ok {
err := resourceAwsAcmCertificateCheckValidationRecords(validation_record_fqdns.(*schema.Set).List(), resp.Certificate)
if err != nil {
return err
}
} else {
log.Printf("[INFO] No validation_record_fqdns set, skipping check")
}
return resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
resp, err := acmconn.DescribeCertificate(params)
if err != nil {
return resource.NonRetryableError(fmt.Errorf("Error describing certificate: %s", err))
}
if *resp.Certificate.Status != "ISSUED" {
return resource.RetryableError(fmt.Errorf("Expected certificate to be issued but was in state %s", *resp.Certificate.Status))
}
log.Printf("[INFO] ACM Certificate validation for %s done, certificate was issued", certificate_arn)
return resource.NonRetryableError(resourceAwsAcmCertificateValidationRead(d, meta))
})
}
func resourceAwsAcmCertificateCheckValidationRecords(validation_record_fqdns []interface{}, cert *acm.CertificateDetail) error {
expected_fqdns := make([]string, len(cert.DomainValidationOptions))
for i, v := range cert.DomainValidationOptions {
if *v.ValidationMethod == acm.ValidationMethodDns {
expected_fqdns[i] = strings.TrimSuffix(*v.ResourceRecord.Name, ".")
}
}
actual_validation_record_fqdns := make([]string, 0, len(validation_record_fqdns))
for _, v := range validation_record_fqdns {
val := v.(string)
actual_validation_record_fqdns = append(actual_validation_record_fqdns, strings.TrimSuffix(val, "."))
}
sort.Strings(expected_fqdns)
sort.Strings(actual_validation_record_fqdns)
log.Printf("[DEBUG] Checking validation_record_fqdns. Expected: %v, Actual: %v", expected_fqdns, actual_validation_record_fqdns)
if !reflect.DeepEqual(expected_fqdns, actual_validation_record_fqdns) {
return fmt.Errorf("Certificate needs %v to be set but only %v was passed to validation_record_fqdns", expected_fqdns, actual_validation_record_fqdns)
}
return nil
}
func resourceAwsAcmCertificateValidationRead(d *schema.ResourceData, meta interface{}) error {
acmconn := meta.(*AWSClient).acmconn
params := &acm.DescribeCertificateInput{
CertificateArn: aws.String(d.Get("certificate_arn").(string)),
}
resp, err := acmconn.DescribeCertificate(params)
if err != nil && isAWSErr(err, acm.ErrCodeResourceNotFoundException, "") {
d.SetId("")
return nil
} else if err != nil {
return fmt.Errorf("Error describing certificate: %s", err)
}
if *resp.Certificate.Status != "ISSUED" {
log.Printf("[INFO] Certificate status not issued, was %s, tainting validation", *resp.Certificate.Status)
d.SetId("")
} else {
d.SetId((*resp.Certificate.IssuedAt).String())
}
return nil
}
func resourceAwsAcmCertificateValidationDelete(d *schema.ResourceData, meta interface{}) error {
// No need to do anything, certificate will be deleted when acm_certificate is deleted
d.SetId("")
return nil
}