providers/aws: Retry deleting IAM Server Cert on dependency violation
This will retry deleting a server cert if it throws an error about being in use with an ELB (that we've likely just deleted) Includes test for ELB+IAM SSL cert bug dependency violation
This commit is contained in:
parent
b6aed3fec3
commit
c60a963908
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
|
@ -256,8 +257,23 @@ func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error {
|
|||
}
|
||||
|
||||
log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts)
|
||||
if _, err := elbconn.CreateLoadBalancer(elbOpts); err != nil {
|
||||
return fmt.Errorf("Error creating ELB: %s", err)
|
||||
err = resource.Retry(1*time.Minute, func() error {
|
||||
_, err := elbconn.CreateLoadBalancer(elbOpts)
|
||||
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
// Check for IAM SSL Cert error, eventual consistancy issue
|
||||
if awsErr.Code() == "CertificateNotFound" {
|
||||
return fmt.Errorf("[WARN] Error creating ELB Listener with SSL Cert, retrying: %s", err)
|
||||
}
|
||||
}
|
||||
return resource.RetryError{Err: err}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Assign the elb's unique identifier for use later
|
||||
|
|
|
@ -179,6 +179,33 @@ func TestAccAWSELB_tags(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSELB_iam_server_cert(t *testing.T) {
|
||||
var conf elb.LoadBalancerDescription
|
||||
// var td elb.TagDescription
|
||||
testCheck := func(*terraform.State) error {
|
||||
if len(conf.ListenerDescriptions) != 1 {
|
||||
return fmt.Errorf(
|
||||
"TestAccAWSELB_iam_server_cert expected 1 listener, got %d",
|
||||
len(conf.ListenerDescriptions))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSELBDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccELBIAMServerCertConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSELBExists("aws_elb.bar", &conf),
|
||||
testCheck,
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccLoadTags(conf *elb.LoadBalancerDescription, td *elb.TagDescription) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).elbconn
|
||||
|
@ -1001,3 +1028,97 @@ resource "aws_security_group" "bar" {
|
|||
}
|
||||
}
|
||||
`
|
||||
|
||||
// This IAM Server config is lifted from
|
||||
// builtin/providers/aws/resource_aws_iam_server_certificate_test.go
|
||||
var testAccELBIAMServerCertConfig = `
|
||||
resource "aws_iam_server_certificate" "test_cert" {
|
||||
name = "terraform-test-cert"
|
||||
certificate_body = <<EOF
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCDCCAfACAQEwDQYJKoZIhvcNAQELBQAwgY4xCzAJBgNVBAYTAlVTMREwDwYD
|
||||
VQQIDAhOZXcgWW9yazERMA8GA1UEBwwITmV3IFlvcmsxFjAUBgNVBAoMDUJhcmVm
|
||||
b290IExhYnMxGDAWBgNVBAMMD0phc29uIEJlcmxpbnNreTEnMCUGCSqGSIb3DQEJ
|
||||
ARYYamFzb25AYmFyZWZvb3Rjb2RlcnMuY29tMB4XDTE1MDYyMTA1MzcwNVoXDTE2
|
||||
MDYyMDA1MzcwNVowgYgxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEL
|
||||
MAkGA1UEBwwCTlkxFjAUBgNVBAoMDUJhcmVmb290IExhYnMxGDAWBgNVBAMMD0ph
|
||||
c29uIEJlcmxpbnNreTEnMCUGCSqGSIb3DQEJARYYamFzb25AYmFyZWZvb3Rjb2Rl
|
||||
cnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2AVGKRIx+EFM0kkg7
|
||||
6GoJv9uy0biEDHB4phQBqnDIf8J8/gq9eVvQrR5jJC9Uz4zp5wG/oLZlGuF92/jD
|
||||
bI/yS+DOAjrh30vN79Au74jGN2Cw8fIak40iDUwjZaczK2Gkna54XIO9pqMcbQ6Q
|
||||
mLUkQXsqlJ7Q4X2kL3b9iMsXcQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCDGNvU
|
||||
eioQMVPNlmmxW3+Rwo0Kl+/HtUOmqUDKUDvJnelxulBr7O8w75N/Z7h7+aBJCUkt
|
||||
tz+DwATZswXtsal6TuzHHpAhpFql82jQZVE8OYkrX84XKRQpm8ZnbyZObMdXTJWk
|
||||
ArC/rGVIWsvhlbgGM8zu7a3zbeuAESZ8Bn4ZbJxnoaRK8p36/alvzAwkgzSf3oUX
|
||||
HtU4LrdunevBs6/CbKCWrxYcvNCy8EcmHitqCfQL5nxCCXpgf/Mw1vmIPTwbPSJq
|
||||
oUkh5yjGRKzhh7QbG1TlFX6zUp4vb+UJn5+g4edHrqivRSjIqYrC45ygVMOABn21
|
||||
hpMXOlZL+YXfR4Kp
|
||||
-----END CERTIFICATE-----
|
||||
EOF
|
||||
|
||||
certificate_chain = <<EOF
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID8TCCAtmgAwIBAgIJAKX2xeCkfFcbMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD
|
||||
VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYw
|
||||
FAYDVQQKDA1CYXJlZm9vdCBMYWJzMRgwFgYDVQQDDA9KYXNvbiBCZXJsaW5za3kx
|
||||
JzAlBgkqhkiG9w0BCQEWGGphc29uQGJhcmVmb290Y29kZXJzLmNvbTAeFw0xNTA2
|
||||
MjEwNTM2MDZaFw0yNTA2MTgwNTM2MDZaMIGOMQswCQYDVQQGEwJVUzERMA8GA1UE
|
||||
CAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYwFAYDVQQKDA1CYXJlZm9v
|
||||
dCBMYWJzMRgwFgYDVQQDDA9KYXNvbiBCZXJsaW5za3kxJzAlBgkqhkiG9w0BCQEW
|
||||
GGphc29uQGJhcmVmb290Y29kZXJzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAMteFbwfLz7NyQn3eDxxw22l1ZPBrzfPON0HOAq8nHat4kT4A2cI
|
||||
45kCtxKMzCVoG84tXoX/rbjGkez7lz9lEfvEuSh+I+UqinFA/sefhcE63foVMZu1
|
||||
2t6O3+utdxBvOYJwAQaiGW44x0h6fTyqDv6Gc5Ml0uoIVeMWPhT1MREoOcPDz1gb
|
||||
Ep3VT2aqFULLJedP37qbzS4D04rn1tS7pcm3wYivRyjVNEvs91NsWEvvE1WtS2Cl
|
||||
2RBt+ihXwq4UNB9UPYG75+FuRcQQvfqameyweyKT9qBmJLELMtYa/KTCYvSch4JY
|
||||
YVPAPOlhFlO4BcTto/gpBes2WEAWZtE/jnECAwEAAaNQME4wHQYDVR0OBBYEFOna
|
||||
aiYnm5583EY7FT/mXwTBuLZgMB8GA1UdIwQYMBaAFOnaaiYnm5583EY7FT/mXwTB
|
||||
uLZgMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABp/dKQ489CCzzB1
|
||||
IX78p6RFAdda4e3lL6uVjeS3itzFIIiKvdf1/txhmsEeCEYz0El6aMnXLkpk7jAr
|
||||
kCwlAOOz2R2hlA8k8opKTYX4IQQau8DATslUFAFOvRGOim/TD/Yuch+a/VF2VQKz
|
||||
L2lUVi5Hjp9KvWe2HQYPjnJaZs/OKAmZQ4uP547dqFrTz6sWfisF1rJ60JH70cyM
|
||||
qjZQp/xYHTZIB8TCPvLgtVIGFmd/VAHVBFW2p9IBwtSxBIsEPwYQOV3XbwhhmGIv
|
||||
DWx5TpnEzH7ZM33RNbAKcdwOBxdRY+SI/ua5hYCm4QngAqY69lEuk4zXZpdDLPq1
|
||||
qxxQx0E=
|
||||
-----END CERTIFICATE-----
|
||||
EOF
|
||||
|
||||
private_key = <<EOF
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQD2AVGKRIx+EFM0kkg76GoJv9uy0biEDHB4phQBqnDIf8J8/gq9
|
||||
eVvQrR5jJC9Uz4zp5wG/oLZlGuF92/jDbI/yS+DOAjrh30vN79Au74jGN2Cw8fIa
|
||||
k40iDUwjZaczK2Gkna54XIO9pqMcbQ6QmLUkQXsqlJ7Q4X2kL3b9iMsXcQIDAQAB
|
||||
AoGALmVBQ5p6BKx/hMKx7NqAZSZSAP+clQrji12HGGlUq/usanZfAC0LK+f6eygv
|
||||
5QbfxJ1UrxdYTukq7dm2qOSooOMUuukWInqC6ztjdLwH70CKnl0bkNB3/NkW2VNc
|
||||
32YiUuZCM9zaeBuEUclKNs+dhD2EeGdJF8KGntWGOTU/M4ECQQD9gdYb38PvaMdu
|
||||
opM3sKJF5n9pMoLDleBpCGqq3nD3DFn0V6PHQAwn30EhRN+7BbUEpde5PmfoIdAR
|
||||
uDlj/XPlAkEA+GyY1e4uU9rz+1K4ubxmtXTp9ZIR2LsqFy5L/MS5hqX2zq5GGq8g
|
||||
jZYDxnxPEUrxaWQH4nh0qdu3skUBi4a0nQJBAKJaqLkpUd7eB/t++zHLWeHSgP7q
|
||||
bny8XABod4f+9fICYwntpuJQzngqrxeTeIXaXdggLkxg/0LXhN4UUg0LoVECQQDE
|
||||
Pi1h2dyY+37/CzLH7q+IKopjJneYqQmv9C+sxs70MgjM7liM3ckub9IdqrdfJr+c
|
||||
DJw56APo5puvZNm6mbf1AkBVMDyfdOOyoHpJjrhmZWo6QqynujfwErrBYQ0sZQ3l
|
||||
O57Z0RUNQ8DRyymhLd2t5nAHTfpcFA1sBeKE6CziLbZB
|
||||
-----END RSA PRIVATE KEY-----
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_elb" "bar" {
|
||||
name = "foobar-terraform-test"
|
||||
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
|
||||
|
||||
listener {
|
||||
instance_port = 8000
|
||||
instance_protocol = "https"
|
||||
lb_port = 80
|
||||
// Protocol should be case insensitive
|
||||
lb_protocol = "HttPs"
|
||||
ssl_certificate_id = "${aws_iam_server_certificate.test_cert.arn}"
|
||||
}
|
||||
|
||||
tags {
|
||||
bar = "baz"
|
||||
}
|
||||
|
||||
cross_zone_load_balancing = true
|
||||
}
|
||||
`
|
||||
|
|
|
@ -6,10 +6,12 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
|
@ -124,14 +126,24 @@ func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{
|
|||
|
||||
func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).iamconn
|
||||
_, err := conn.DeleteServerCertificate(&iam.DeleteServerCertificateInput{
|
||||
ServerCertificateName: aws.String(d.Get("name").(string)),
|
||||
log.Printf("[INFO] Deleting IAM Server Certificate: %s", d.Id())
|
||||
err := resource.Retry(1*time.Minute, func() error {
|
||||
_, err := conn.DeleteServerCertificate(&iam.DeleteServerCertificateInput{
|
||||
ServerCertificateName: aws.String(d.Get("name").(string)),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
if awsErr.Code() == "DeleteConflict" && strings.Contains(awsErr.Message(), "currently in use by arn") {
|
||||
return fmt.Errorf("[WARN] Conflict deleting server certificate: %s, retrying", awsErr.Message())
|
||||
}
|
||||
}
|
||||
return resource.RetryError{Err: err}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
return fmt.Errorf("[WARN] Error deleting server certificate: %s: %s", awsErr.Code(), awsErr.Message())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -44,24 +44,24 @@ func expandListeners(configured []interface{}) ([]*elb.Listener, error) {
|
|||
l.SSLCertificateId = aws.String(v.(string))
|
||||
}
|
||||
|
||||
var valid bool
|
||||
if l.SSLCertificateId != nil && *l.SSLCertificateId != "" {
|
||||
// validate the protocol is correct
|
||||
for _, p := range []string{"https", "ssl"} {
|
||||
if (*l.InstanceProtocol == p) || (*l.Protocol == p) {
|
||||
valid = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
valid = true
|
||||
}
|
||||
var valid bool
|
||||
if l.SSLCertificateId != nil && *l.SSLCertificateId != "" {
|
||||
// validate the protocol is correct
|
||||
for _, p := range []string{"https", "ssl"} {
|
||||
if (*l.InstanceProtocol == p) || (*l.Protocol == p) {
|
||||
valid = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
valid = true
|
||||
}
|
||||
|
||||
if valid {
|
||||
listeners = append(listeners, l)
|
||||
} else {
|
||||
return nil, fmt.Errorf("[ERR] ELB Listener: ssl_certificate_id may be set only when protocol is 'https' or 'ssl'")
|
||||
}
|
||||
}
|
||||
if valid {
|
||||
listeners = append(listeners, l)
|
||||
} else {
|
||||
return nil, fmt.Errorf("[ERR] ELB Listener: ssl_certificate_id may be set only when protocol is 'https' or 'ssl'")
|
||||
}
|
||||
}
|
||||
|
||||
return listeners, nil
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package aws
|
|||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
|
@ -296,13 +296,13 @@ func TestExpandListeners(t *testing.T) {
|
|||
"instance_protocol": "http",
|
||||
"lb_protocol": "http",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"instance_port": 8000,
|
||||
"lb_port": 80,
|
||||
"instance_protocol": "https",
|
||||
"lb_protocol": "https",
|
||||
"ssl_certificate_id": "something",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"instance_port": 8000,
|
||||
"lb_port": 80,
|
||||
"instance_protocol": "https",
|
||||
"lb_protocol": "https",
|
||||
"ssl_certificate_id": "something",
|
||||
},
|
||||
}
|
||||
listeners, err := expandListeners(expanded)
|
||||
if err != nil {
|
||||
|
@ -327,26 +327,26 @@ func TestExpandListeners(t *testing.T) {
|
|||
// this test should produce an error from expandlisteners on an invalid
|
||||
// combination
|
||||
func TestExpandListeners_invalid(t *testing.T) {
|
||||
expanded := []interface{}{
|
||||
map[string]interface{}{
|
||||
"instance_port": 8000,
|
||||
"lb_port": 80,
|
||||
"instance_protocol": "http",
|
||||
"lb_protocol": "http",
|
||||
"ssl_certificate_id": "something",
|
||||
},
|
||||
}
|
||||
_, err := expandListeners(expanded)
|
||||
if err != nil {
|
||||
// Check the error we got
|
||||
if !strings.Contains(err.Error(), "ssl_certificate_id may be set only when protocol") {
|
||||
t.Fatalf("Got error in TestExpandListeners_invalid, but not what we expected: %s", err)
|
||||
}
|
||||
}
|
||||
expanded := []interface{}{
|
||||
map[string]interface{}{
|
||||
"instance_port": 8000,
|
||||
"lb_port": 80,
|
||||
"instance_protocol": "http",
|
||||
"lb_protocol": "http",
|
||||
"ssl_certificate_id": "something",
|
||||
},
|
||||
}
|
||||
_, err := expandListeners(expanded)
|
||||
if err != nil {
|
||||
// Check the error we got
|
||||
if !strings.Contains(err.Error(), "ssl_certificate_id may be set only when protocol") {
|
||||
t.Fatalf("Got error in TestExpandListeners_invalid, but not what we expected: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("Expected TestExpandListeners_invalid to fail, but passed")
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("Expected TestExpandListeners_invalid to fail, but passed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlattenHealthCheck(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue