implement flexible resources for ELB Policies
allows load balancer policies and their assignment to backend servers or listeners to be configured independently. this gives flexibility to configure additional policies on aws elastic load balancers aside from the already provided "convenience" wrappers for cookie stickiness
This commit is contained in:
parent
c965d9bea4
commit
ecadf103cc
|
@ -215,6 +215,9 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_lambda_permission": resourceAwsLambdaPermission(),
|
"aws_lambda_permission": resourceAwsLambdaPermission(),
|
||||||
"aws_launch_configuration": resourceAwsLaunchConfiguration(),
|
"aws_launch_configuration": resourceAwsLaunchConfiguration(),
|
||||||
"aws_lb_cookie_stickiness_policy": resourceAwsLBCookieStickinessPolicy(),
|
"aws_lb_cookie_stickiness_policy": resourceAwsLBCookieStickinessPolicy(),
|
||||||
|
"aws_elb_load_balancer_policy": resourceAwsLoadBalancerPolicy(),
|
||||||
|
"aws_elb_load_balancer_backend_server_policy": resourceAwsLoadBalancerBackendServerPolicies(),
|
||||||
|
"aws_elb_load_balancer_listener_policy": resourceAwsLoadBalancerListenerPolicies(),
|
||||||
"aws_main_route_table_association": resourceAwsMainRouteTableAssociation(),
|
"aws_main_route_table_association": resourceAwsMainRouteTableAssociation(),
|
||||||
"aws_nat_gateway": resourceAwsNatGateway(),
|
"aws_nat_gateway": resourceAwsNatGateway(),
|
||||||
"aws_network_acl": resourceAwsNetworkAcl(),
|
"aws_network_acl": resourceAwsNetworkAcl(),
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/elb"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerBackendServerPolicies() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsLoadBalancerBackendServerPoliciesCreate,
|
||||||
|
Read: resourceAwsLoadBalancerBackendServerPoliciesRead,
|
||||||
|
Update: resourceAwsLoadBalancerBackendServerPoliciesCreate,
|
||||||
|
Delete: resourceAwsLoadBalancerBackendServerPoliciesDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"load_balancer_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"policy_names": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
Optional: true,
|
||||||
|
Set: schema.HashString,
|
||||||
|
},
|
||||||
|
|
||||||
|
"instance_port": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerBackendServerPoliciesCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName := d.Get("load_balancer_name")
|
||||||
|
|
||||||
|
policyNames := []*string{}
|
||||||
|
if v, ok := d.GetOk("policy_names"); ok {
|
||||||
|
policyNames = expandStringList(v.(*schema.Set).List())
|
||||||
|
}
|
||||||
|
|
||||||
|
setOpts := &elb.SetLoadBalancerPoliciesForBackendServerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName.(string)),
|
||||||
|
InstancePort: aws.Int64(int64(d.Get("instance_port").(int))),
|
||||||
|
PolicyNames: policyNames,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := elbconn.SetLoadBalancerPoliciesForBackendServer(setOpts); err != nil {
|
||||||
|
return fmt.Errorf("Error setting LoadBalancerPoliciesForBackendServer: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%s:%s", *setOpts.LoadBalancerName, strconv.FormatInt(*setOpts.InstancePort, 10)))
|
||||||
|
d.Set("load_balancer_name", setOpts.LoadBalancerName)
|
||||||
|
d.Set("instance_port", setOpts.InstancePort)
|
||||||
|
d.Set("policy_names", flattenStringList(setOpts.PolicyNames))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerBackendServerPoliciesRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName, instancePort := resourceAwsLoadBalancerBackendServerPoliciesParseId(d.Id())
|
||||||
|
|
||||||
|
describeElbOpts := &elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
}
|
||||||
|
|
||||||
|
describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok {
|
||||||
|
if ec2err.Code() == "LoadBalancerNotFound" {
|
||||||
|
return fmt.Errorf("LoadBalancerNotFound: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error retrieving ELB description: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(describeResp.LoadBalancerDescriptions) != 1 {
|
||||||
|
return fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
lb := describeResp.LoadBalancerDescriptions[0]
|
||||||
|
|
||||||
|
policyNames := []*string{}
|
||||||
|
for _, backendServer := range lb.BackendServerDescriptions {
|
||||||
|
if instancePort != strconv.Itoa(int(*backendServer.InstancePort)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range backendServer.PolicyNames {
|
||||||
|
policyNames = append(policyNames, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("load_balancer_name", loadBalancerName)
|
||||||
|
d.Set("instance_port", instancePort)
|
||||||
|
d.Set("policy_names", flattenStringList(policyNames))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerBackendServerPoliciesDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName, instancePort := resourceAwsLoadBalancerBackendServerPoliciesParseId(d.Id())
|
||||||
|
|
||||||
|
instancePortInt, err := strconv.ParseInt(instancePort, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error parsing instancePort as integer: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
setOpts := &elb.SetLoadBalancerPoliciesForBackendServerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
InstancePort: aws.Int64(instancePortInt),
|
||||||
|
PolicyNames: []*string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := elbconn.SetLoadBalancerPoliciesForBackendServer(setOpts); err != nil {
|
||||||
|
return fmt.Errorf("Error setting LoadBalancerPoliciesForBackendServer: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerBackendServerPoliciesParseId(id string) (string, string) {
|
||||||
|
parts := strings.SplitN(id, ":", 2)
|
||||||
|
return parts[0], parts[1]
|
||||||
|
}
|
|
@ -0,0 +1,388 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/elb"
|
||||||
|
|
||||||
|
tlsprovider "github.com/hashicorp/terraform/builtin/providers/tls"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSLoadBalancerBackendServerPolicy_basic(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: map[string]terraform.ResourceProvider{
|
||||||
|
"aws": testAccProvider,
|
||||||
|
"tls": tlsprovider.Provider(),
|
||||||
|
},
|
||||||
|
CheckDestroy: testAccCheckAWSLoadBalancerBackendServerPolicyDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerBackendServerPolicyConfig_basic0,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-pubkey-policy0"),
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-backend-auth-policy0"),
|
||||||
|
testAccCheckAWSLoadBalancerBackendServerPolicyState("test-aws-elb-policies-lb", "test-backend-auth-policy0", true),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerBackendServerPolicyConfig_basic1,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-pubkey-policy0"),
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-pubkey-policy1"),
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-backend-auth-policy0"),
|
||||||
|
testAccCheckAWSLoadBalancerBackendServerPolicyState("test-aws-elb-policies-lb", "test-backend-auth-policy0", true),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerBackendServerPolicyConfig_basic2,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerBackendServerPolicyState("test-aws-elb-policies-lb", "test-backend-auth-policy0", false),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func policyInBackendServerPolicies(str string, list []string) bool {
|
||||||
|
for _, v := range list {
|
||||||
|
if v == str {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSLoadBalancerBackendServerPolicyDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).elbconn
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
switch {
|
||||||
|
case rs.Type == "aws_elb_load_balancer_policy":
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerBackendServerPoliciesParseId(rs.Primary.ID)
|
||||||
|
out, err := conn.DescribeLoadBalancerPolicies(
|
||||||
|
&elb.DescribeLoadBalancerPoliciesInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
PolicyNames: []*string{aws.String(policyName)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && (ec2err.Code() == "PolicyNotFound" || ec2err.Code() == "LoadBalancerNotFound") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(out.PolicyDescriptions) > 0 {
|
||||||
|
return fmt.Errorf("Policy still exists")
|
||||||
|
}
|
||||||
|
case rs.Type == "aws_elb_load_balancer_backend_policy":
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerBackendServerPoliciesParseId(rs.Primary.ID)
|
||||||
|
out, err := conn.DescribeLoadBalancers(
|
||||||
|
&elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && (ec2err.Code() == "LoadBalancerNotFound") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, backendServer := range out.LoadBalancerDescriptions[0].BackendServerDescriptions {
|
||||||
|
policyStrings := []string{}
|
||||||
|
for _, pol := range backendServer.PolicyNames {
|
||||||
|
policyStrings = append(policyStrings, *pol)
|
||||||
|
}
|
||||||
|
if policyInBackendServerPolicies(policyName, policyStrings) {
|
||||||
|
return fmt.Errorf("Policy still exists and is assigned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSLoadBalancerBackendServerPolicyState(loadBalancerName string, loadBalancerBackendAuthPolicyName string, assigned bool) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
elbconn := testAccProvider.Meta().(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerDescription, err := elbconn.DescribeLoadBalancers(&elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, backendServer := range loadBalancerDescription.LoadBalancerDescriptions[0].BackendServerDescriptions {
|
||||||
|
policyStrings := []string{}
|
||||||
|
for _, pol := range backendServer.PolicyNames {
|
||||||
|
policyStrings = append(policyStrings, *pol)
|
||||||
|
}
|
||||||
|
if policyInBackendServerPolicies(loadBalancerBackendAuthPolicyName, policyStrings) != assigned {
|
||||||
|
if assigned {
|
||||||
|
return fmt.Errorf("Policy no longer assigned %s not in %+v", loadBalancerBackendAuthPolicyName, policyStrings)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Policy exists and is assigned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerBackendServerPolicyConfig_basic0 = `
|
||||||
|
resource "tls_private_key" "example0" {
|
||||||
|
algorithm = "RSA"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_self_signed_cert" "test-cert0" {
|
||||||
|
key_algorithm = "RSA"
|
||||||
|
private_key_pem = "${tls_private_key.example0.private_key_pem}"
|
||||||
|
|
||||||
|
subject {
|
||||||
|
common_name = "example.com"
|
||||||
|
organization = "ACME Examples, Inc"
|
||||||
|
}
|
||||||
|
|
||||||
|
validity_period_hours = 12
|
||||||
|
|
||||||
|
allowed_uses = [
|
||||||
|
"key_encipherment",
|
||||||
|
"digital_signature",
|
||||||
|
"server_auth",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_iam_server_certificate" "test-iam-cert0" {
|
||||||
|
name_prefix = "test_cert_"
|
||||||
|
certificate_body = "${tls_self_signed_cert.test-cert0.cert_pem}"
|
||||||
|
private_key = "${tls_private_key.example0.private_key_pem}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 443
|
||||||
|
instance_protocol = "https"
|
||||||
|
lb_port = 443
|
||||||
|
lb_protocol = "https"
|
||||||
|
ssl_certificate_id = "${aws_iam_server_certificate.test-iam-cert0.arn}"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-pubkey-policy0" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-pubkey-policy0"
|
||||||
|
policy_type_name = "PublicKeyPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKey"
|
||||||
|
value = "${replace(replace(replace(tls_private_key.example0.public_key_pem, "\n", ""), "-----BEGIN PUBLIC KEY-----", ""), "-----END PUBLIC KEY-----", "")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-backend-auth-policy0" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-backend-auth-policy0"
|
||||||
|
policy_type_name = "BackendServerAuthenticationPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKeyPolicyName"
|
||||||
|
value = "${aws_elb_load_balancer_policy.test-pubkey-policy0.policy_name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_backend_server_policy" "test-backend-auth-policies-443" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
instance_port = 443
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.test-backend-auth-policy0.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerBackendServerPolicyConfig_basic1 = `
|
||||||
|
resource "tls_private_key" "example0" {
|
||||||
|
algorithm = "RSA"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_self_signed_cert" "test-cert0" {
|
||||||
|
key_algorithm = "RSA"
|
||||||
|
private_key_pem = "${tls_private_key.example0.private_key_pem}"
|
||||||
|
|
||||||
|
subject {
|
||||||
|
common_name = "example.com"
|
||||||
|
organization = "ACME Examples, Inc"
|
||||||
|
}
|
||||||
|
|
||||||
|
validity_period_hours = 12
|
||||||
|
|
||||||
|
allowed_uses = [
|
||||||
|
"key_encipherment",
|
||||||
|
"digital_signature",
|
||||||
|
"server_auth",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_private_key" "example1" {
|
||||||
|
algorithm = "RSA"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_self_signed_cert" "test-cert1" {
|
||||||
|
key_algorithm = "RSA"
|
||||||
|
private_key_pem = "${tls_private_key.example1.private_key_pem}"
|
||||||
|
|
||||||
|
subject {
|
||||||
|
common_name = "example.com"
|
||||||
|
organization = "ACME Examples, Inc"
|
||||||
|
}
|
||||||
|
|
||||||
|
validity_period_hours = 12
|
||||||
|
|
||||||
|
allowed_uses = [
|
||||||
|
"key_encipherment",
|
||||||
|
"digital_signature",
|
||||||
|
"server_auth",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_iam_server_certificate" "test-iam-cert0" {
|
||||||
|
name_prefix = "test_cert_"
|
||||||
|
certificate_body = "${tls_self_signed_cert.test-cert0.cert_pem}"
|
||||||
|
private_key = "${tls_private_key.example0.private_key_pem}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 443
|
||||||
|
instance_protocol = "https"
|
||||||
|
lb_port = 443
|
||||||
|
lb_protocol = "https"
|
||||||
|
ssl_certificate_id = "${aws_iam_server_certificate.test-iam-cert0.arn}"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-pubkey-policy0" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-pubkey-policy0"
|
||||||
|
policy_type_name = "PublicKeyPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKey"
|
||||||
|
value = "${replace(replace(replace(tls_private_key.example0.public_key_pem, "\n", ""), "-----BEGIN PUBLIC KEY-----", ""), "-----END PUBLIC KEY-----", "")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-pubkey-policy1" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-pubkey-policy1"
|
||||||
|
policy_type_name = "PublicKeyPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKey"
|
||||||
|
value = "${replace(replace(replace(tls_private_key.example1.public_key_pem, "\n", ""), "-----BEGIN PUBLIC KEY-----", ""), "-----END PUBLIC KEY-----", "")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-backend-auth-policy0" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-backend-auth-policy0"
|
||||||
|
policy_type_name = "BackendServerAuthenticationPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKeyPolicyName"
|
||||||
|
value = "${aws_elb_load_balancer_policy.test-pubkey-policy1.policy_name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_backend_server_policy" "test-backend-auth-policies-443" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
instance_port = 443
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.test-backend-auth-policy0.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerBackendServerPolicyConfig_basic2 = `
|
||||||
|
resource "tls_private_key" "example0" {
|
||||||
|
algorithm = "RSA"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_self_signed_cert" "test-cert0" {
|
||||||
|
key_algorithm = "RSA"
|
||||||
|
private_key_pem = "${tls_private_key.example0.private_key_pem}"
|
||||||
|
|
||||||
|
subject {
|
||||||
|
common_name = "example.com"
|
||||||
|
organization = "ACME Examples, Inc"
|
||||||
|
}
|
||||||
|
|
||||||
|
validity_period_hours = 12
|
||||||
|
|
||||||
|
allowed_uses = [
|
||||||
|
"key_encipherment",
|
||||||
|
"digital_signature",
|
||||||
|
"server_auth",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_private_key" "example1" {
|
||||||
|
algorithm = "RSA"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_self_signed_cert" "test-cert1" {
|
||||||
|
key_algorithm = "RSA"
|
||||||
|
private_key_pem = "${tls_private_key.example1.private_key_pem}"
|
||||||
|
|
||||||
|
subject {
|
||||||
|
common_name = "example.com"
|
||||||
|
organization = "ACME Examples, Inc"
|
||||||
|
}
|
||||||
|
|
||||||
|
validity_period_hours = 12
|
||||||
|
|
||||||
|
allowed_uses = [
|
||||||
|
"key_encipherment",
|
||||||
|
"digital_signature",
|
||||||
|
"server_auth",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_iam_server_certificate" "test-iam-cert0" {
|
||||||
|
name_prefix = "test_cert_"
|
||||||
|
certificate_body = "${tls_self_signed_cert.test-cert0.cert_pem}"
|
||||||
|
private_key = "${tls_private_key.example0.private_key_pem}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 443
|
||||||
|
instance_protocol = "https"
|
||||||
|
lb_port = 443
|
||||||
|
lb_protocol = "https"
|
||||||
|
ssl_certificate_id = "${aws_iam_server_certificate.test-iam-cert0.arn}"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,139 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/elb"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerListenerPolicies() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsLoadBalancerListenerPoliciesCreate,
|
||||||
|
Read: resourceAwsLoadBalancerListenerPoliciesRead,
|
||||||
|
Update: resourceAwsLoadBalancerListenerPoliciesCreate,
|
||||||
|
Delete: resourceAwsLoadBalancerListenerPoliciesDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"load_balancer_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"policy_names": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
Optional: true,
|
||||||
|
Set: schema.HashString,
|
||||||
|
},
|
||||||
|
|
||||||
|
"load_balancer_port": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerListenerPoliciesCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName := d.Get("load_balancer_name")
|
||||||
|
|
||||||
|
policyNames := []*string{}
|
||||||
|
if v, ok := d.GetOk("policy_names"); ok {
|
||||||
|
policyNames = expandStringList(v.(*schema.Set).List())
|
||||||
|
}
|
||||||
|
|
||||||
|
setOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName.(string)),
|
||||||
|
LoadBalancerPort: aws.Int64(int64(d.Get("load_balancer_port").(int))),
|
||||||
|
PolicyNames: policyNames,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setOpts); err != nil {
|
||||||
|
return fmt.Errorf("Error setting LoadBalancerPoliciesOfListener: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%s:%s", *setOpts.LoadBalancerName, strconv.FormatInt(*setOpts.LoadBalancerPort, 10)))
|
||||||
|
d.Set("load_balancer_name", setOpts.LoadBalancerName)
|
||||||
|
d.Set("load_balancer_port", setOpts.LoadBalancerPort)
|
||||||
|
d.Set("policy_names", flattenStringList(setOpts.PolicyNames))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerListenerPoliciesRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName, loadBalancerPort := resourceAwsLoadBalancerListenerPoliciesParseId(d.Id())
|
||||||
|
|
||||||
|
describeElbOpts := &elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
}
|
||||||
|
|
||||||
|
describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok {
|
||||||
|
if ec2err.Code() == "LoadBalancerNotFound" {
|
||||||
|
return fmt.Errorf("LoadBalancerNotFound: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error retrieving ELB description: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(describeResp.LoadBalancerDescriptions) != 1 {
|
||||||
|
return fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
lb := describeResp.LoadBalancerDescriptions[0]
|
||||||
|
|
||||||
|
policyNames := []*string{}
|
||||||
|
for _, listener := range lb.ListenerDescriptions {
|
||||||
|
if loadBalancerPort != strconv.Itoa(int(*listener.Listener.LoadBalancerPort)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range listener.PolicyNames {
|
||||||
|
policyNames = append(policyNames, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("load_balancer_name", loadBalancerName)
|
||||||
|
d.Set("load_balancer_port", loadBalancerPort)
|
||||||
|
d.Set("policy_names", flattenStringList(policyNames))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerListenerPoliciesDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName, loadBalancerPort := resourceAwsLoadBalancerListenerPoliciesParseId(d.Id())
|
||||||
|
|
||||||
|
loadBalancerPortInt, err := strconv.ParseInt(loadBalancerPort, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error parsing loadBalancerPort as integer: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
setOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
LoadBalancerPort: aws.Int64(loadBalancerPortInt),
|
||||||
|
PolicyNames: []*string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setOpts); err != nil {
|
||||||
|
return fmt.Errorf("Error setting LoadBalancerPoliciesOfListener: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerListenerPoliciesParseId(id string) (string, string) {
|
||||||
|
parts := strings.SplitN(id, ":", 2)
|
||||||
|
return parts[0], parts[1]
|
||||||
|
}
|
|
@ -0,0 +1,233 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/elb"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSLoadBalancerListenerPolicy_basic(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSLoadBalancerListenerPolicyDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerListenerPolicyConfig_basic0,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.magic-cookie-sticky"),
|
||||||
|
testAccCheckAWSLoadBalancerListenerPolicyState("test-aws-elb-policies-lb", int64(80), "magic-cookie-sticky-policy", true),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerListenerPolicyConfig_basic1,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.magic-cookie-sticky"),
|
||||||
|
testAccCheckAWSLoadBalancerListenerPolicyState("test-aws-elb-policies-lb", int64(80), "magic-cookie-sticky-policy", true),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerListenerPolicyConfig_basic2,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerListenerPolicyState("test-aws-elb-policies-lb", int64(80), "magic-cookie-sticky-policy", false),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func policyInListenerPolicies(str string, list []string) bool {
|
||||||
|
for _, v := range list {
|
||||||
|
if v == str {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSLoadBalancerListenerPolicyDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).elbconn
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
switch {
|
||||||
|
case rs.Type == "aws_elb_load_balancer_policy":
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerListenerPoliciesParseId(rs.Primary.ID)
|
||||||
|
out, err := conn.DescribeLoadBalancerPolicies(
|
||||||
|
&elb.DescribeLoadBalancerPoliciesInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
PolicyNames: []*string{aws.String(policyName)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && (ec2err.Code() == "PolicyNotFound" || ec2err.Code() == "LoadBalancerNotFound") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(out.PolicyDescriptions) > 0 {
|
||||||
|
return fmt.Errorf("Policy still exists")
|
||||||
|
}
|
||||||
|
case rs.Type == "aws_elb_load_listener_policy":
|
||||||
|
loadBalancerName, _ := resourceAwsLoadBalancerListenerPoliciesParseId(rs.Primary.ID)
|
||||||
|
out, err := conn.DescribeLoadBalancers(
|
||||||
|
&elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && (ec2err.Code() == "LoadBalancerNotFound") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
policyNames := []string{}
|
||||||
|
for k, _ := range rs.Primary.Attributes {
|
||||||
|
if strings.HasPrefix(k, "policy_names.") && strings.HasSuffix(k, ".name") {
|
||||||
|
value_key := fmt.Sprintf("%s.value", strings.TrimSuffix(k, ".name"))
|
||||||
|
policyNames = append(policyNames, rs.Primary.Attributes[value_key])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, policyName := range policyNames {
|
||||||
|
for _, listener := range out.LoadBalancerDescriptions[0].ListenerDescriptions {
|
||||||
|
policyStrings := []string{}
|
||||||
|
for _, pol := range listener.PolicyNames {
|
||||||
|
policyStrings = append(policyStrings, *pol)
|
||||||
|
}
|
||||||
|
if policyInListenerPolicies(policyName, policyStrings) {
|
||||||
|
return fmt.Errorf("Policy still exists and is assigned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSLoadBalancerListenerPolicyState(loadBalancerName string, loadBalancerListenerPort int64, loadBalancerListenerPolicyName string, assigned bool) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
elbconn := testAccProvider.Meta().(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerDescription, err := elbconn.DescribeLoadBalancers(&elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, listener := range loadBalancerDescription.LoadBalancerDescriptions[0].ListenerDescriptions {
|
||||||
|
if *listener.Listener.LoadBalancerPort != loadBalancerListenerPort {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
policyStrings := []string{}
|
||||||
|
for _, pol := range listener.PolicyNames {
|
||||||
|
policyStrings = append(policyStrings, *pol)
|
||||||
|
}
|
||||||
|
if policyInListenerPolicies(loadBalancerListenerPolicyName, policyStrings) != assigned {
|
||||||
|
if assigned {
|
||||||
|
return fmt.Errorf("Policy no longer assigned %s not in %+v", loadBalancerListenerPolicyName, policyStrings)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Policy exists and is assigned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerListenerPolicyConfig_basic0 = `
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 80
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 80
|
||||||
|
lb_protocol = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "magic-cookie-sticky" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "magic-cookie-sticky-policy"
|
||||||
|
policy_type_name = "AppCookieStickinessPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "CookieName"
|
||||||
|
value = "magic_cookie"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_listener_policy" "test-lb-listener-policies-80" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
load_balancer_port = 80
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.magic-cookie-sticky.policy_name}",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerListenerPolicyConfig_basic1 = `
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 80
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 80
|
||||||
|
lb_protocol = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "magic-cookie-sticky" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "magic-cookie-sticky-policy"
|
||||||
|
policy_type_name = "AppCookieStickinessPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "CookieName"
|
||||||
|
value = "unicorn_cookie"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_listener_policy" "test-lb-listener-policies-80" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
load_balancer_port = 80
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.magic-cookie-sticky.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerListenerPolicyConfig_basic2 = `
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 80
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 80
|
||||||
|
lb_protocol = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,350 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/elb"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicy() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsLoadBalancerPolicyCreate,
|
||||||
|
Read: resourceAwsLoadBalancerPolicyRead,
|
||||||
|
Update: resourceAwsLoadBalancerPolicyUpdate,
|
||||||
|
Delete: resourceAwsLoadBalancerPolicyDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"load_balancer_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"policy_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"policy_type_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"policy_attribute": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"value": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicyCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
attributes := []*elb.PolicyAttribute{}
|
||||||
|
if attributedata, ok := d.GetOk("policy_attribute"); ok {
|
||||||
|
attributeSet := attributedata.(*schema.Set).List()
|
||||||
|
for _, attribute := range attributeSet {
|
||||||
|
data := attribute.(map[string]interface{})
|
||||||
|
attributes = append(attributes, &elb.PolicyAttribute{
|
||||||
|
AttributeName: aws.String(data["name"].(string)),
|
||||||
|
AttributeValue: aws.String(data["value"].(string)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lbspOpts := &elb.CreateLoadBalancerPolicyInput{
|
||||||
|
LoadBalancerName: aws.String(d.Get("load_balancer_name").(string)),
|
||||||
|
PolicyName: aws.String(d.Get("policy_name").(string)),
|
||||||
|
PolicyTypeName: aws.String(d.Get("policy_type_name").(string)),
|
||||||
|
PolicyAttributes: attributes,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := elbconn.CreateLoadBalancerPolicy(lbspOpts); err != nil {
|
||||||
|
return fmt.Errorf("Error creating LoadBalancerPolicy: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%s:%s",
|
||||||
|
*lbspOpts.LoadBalancerName,
|
||||||
|
*lbspOpts.PolicyName))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicyRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(d.Id())
|
||||||
|
|
||||||
|
request := &elb.DescribeLoadBalancerPoliciesInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
PolicyNames: []*string{aws.String(policyName)},
|
||||||
|
}
|
||||||
|
|
||||||
|
getResp, err := elbconn.DescribeLoadBalancerPolicies(request)
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "PolicyNotFound" {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error retrieving policy: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(getResp.PolicyDescriptions) != 1 {
|
||||||
|
return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
policyDesc := getResp.PolicyDescriptions[0]
|
||||||
|
policyTypeName := policyDesc.PolicyTypeName
|
||||||
|
policyAttributes := policyDesc.PolicyAttributeDescriptions
|
||||||
|
|
||||||
|
attributes := []map[string]string{}
|
||||||
|
for _, a := range policyAttributes {
|
||||||
|
pair := make(map[string]string)
|
||||||
|
pair["name"] = *a.AttributeName
|
||||||
|
pair["value"] = *a.AttributeValue
|
||||||
|
if (*policyTypeName == "SSLNegotiationPolicyType") && (*a.AttributeValue == "false") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributes = append(attributes, pair)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("policy_name", policyName)
|
||||||
|
d.Set("policy_type_name", policyTypeName)
|
||||||
|
d.Set("load_balancer_name", loadBalancerName)
|
||||||
|
d.Set("policy_attribute", attributes)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
reassignments := Reassignment{}
|
||||||
|
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(d.Id())
|
||||||
|
|
||||||
|
assigned, err := resourceAwsLoadBalancerPolicyAssigned(policyName, loadBalancerName, elbconn)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error determining assignment status of Load Balancer Policy %s: %s", policyName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if assigned {
|
||||||
|
reassignments, err = resourceAwsLoadBalancerPolicyUnassign(policyName, loadBalancerName, elbconn)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error unassigning Load Balancer Policy %s: %s", policyName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request := &elb.DeleteLoadBalancerPolicyInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
PolicyName: aws.String(policyName),
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting Load Balancer Policy %s: %s", d.Id(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resourceAwsLoadBalancerPolicyCreate(d, meta)
|
||||||
|
|
||||||
|
for _, listenerAssignment := range reassignments.listenerPolicies {
|
||||||
|
if _, err := elbconn.SetLoadBalancerPoliciesOfListener(listenerAssignment); err != nil {
|
||||||
|
return fmt.Errorf("Error setting LoadBalancerPoliciesOfListener: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, backendServerAssignment := range reassignments.backendServerPolicies {
|
||||||
|
if _, err := elbconn.SetLoadBalancerPoliciesForBackendServer(backendServerAssignment); err != nil {
|
||||||
|
return fmt.Errorf("Error setting LoadBalancerPoliciesForBackendServer: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicyDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
elbconn := meta.(*AWSClient).elbconn
|
||||||
|
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(d.Id())
|
||||||
|
|
||||||
|
assigned, err := resourceAwsLoadBalancerPolicyAssigned(policyName, loadBalancerName, elbconn)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error determining assignment status of Load Balancer Policy %s: %s", policyName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if assigned {
|
||||||
|
_, err := resourceAwsLoadBalancerPolicyUnassign(policyName, loadBalancerName, elbconn)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error unassigning Load Balancer Policy %s: %s", policyName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request := &elb.DeleteLoadBalancerPolicyInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
PolicyName: aws.String(policyName),
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting Load Balancer Policy %s: %s", d.Id(), err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicyParseId(id string) (string, string) {
|
||||||
|
parts := strings.SplitN(id, ":", 2)
|
||||||
|
return parts[0], parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicyAssigned(policyName, loadBalancerName string, elbconn *elb.ELB) (bool, error) {
|
||||||
|
describeElbOpts := &elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
}
|
||||||
|
|
||||||
|
describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok {
|
||||||
|
if ec2err.Code() == "LoadBalancerNotFound" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, fmt.Errorf("Error retrieving ELB description: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(describeResp.LoadBalancerDescriptions) != 1 {
|
||||||
|
return false, fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
lb := describeResp.LoadBalancerDescriptions[0]
|
||||||
|
assigned := false
|
||||||
|
for _, backendServer := range lb.BackendServerDescriptions {
|
||||||
|
for _, name := range backendServer.PolicyNames {
|
||||||
|
if policyName == *name {
|
||||||
|
assigned = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, listener := range lb.ListenerDescriptions {
|
||||||
|
for _, name := range listener.PolicyNames {
|
||||||
|
if policyName == *name {
|
||||||
|
assigned = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return assigned, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Reassignment struct {
|
||||||
|
backendServerPolicies []*elb.SetLoadBalancerPoliciesForBackendServerInput
|
||||||
|
listenerPolicies []*elb.SetLoadBalancerPoliciesOfListenerInput
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsLoadBalancerPolicyUnassign(policyName, loadBalancerName string, elbconn *elb.ELB) (Reassignment, error) {
|
||||||
|
reassignments := Reassignment{}
|
||||||
|
|
||||||
|
describeElbOpts := &elb.DescribeLoadBalancersInput{
|
||||||
|
LoadBalancerNames: []*string{aws.String(loadBalancerName)},
|
||||||
|
}
|
||||||
|
|
||||||
|
describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok {
|
||||||
|
if ec2err.Code() == "LoadBalancerNotFound" {
|
||||||
|
return reassignments, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reassignments, fmt.Errorf("Error retrieving ELB description: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(describeResp.LoadBalancerDescriptions) != 1 {
|
||||||
|
return reassignments, fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
lb := describeResp.LoadBalancerDescriptions[0]
|
||||||
|
|
||||||
|
for _, backendServer := range lb.BackendServerDescriptions {
|
||||||
|
policies := []*string{}
|
||||||
|
|
||||||
|
for _, name := range backendServer.PolicyNames {
|
||||||
|
if policyName != *name {
|
||||||
|
policies = append(policies, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(backendServer.PolicyNames) != len(policies) {
|
||||||
|
setOpts := &elb.SetLoadBalancerPoliciesForBackendServerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
InstancePort: aws.Int64(*backendServer.InstancePort),
|
||||||
|
PolicyNames: policies,
|
||||||
|
}
|
||||||
|
|
||||||
|
reassignOpts := &elb.SetLoadBalancerPoliciesForBackendServerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
InstancePort: aws.Int64(*backendServer.InstancePort),
|
||||||
|
PolicyNames: backendServer.PolicyNames,
|
||||||
|
}
|
||||||
|
|
||||||
|
reassignments.backendServerPolicies = append(reassignments.backendServerPolicies, reassignOpts)
|
||||||
|
|
||||||
|
_, err = elbconn.SetLoadBalancerPoliciesForBackendServer(setOpts)
|
||||||
|
if err != nil {
|
||||||
|
return reassignments, fmt.Errorf("Error Setting Load Balancer Policies for Backend Server: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, listener := range lb.ListenerDescriptions {
|
||||||
|
policies := []*string{}
|
||||||
|
|
||||||
|
for _, name := range listener.PolicyNames {
|
||||||
|
if policyName != *name {
|
||||||
|
policies = append(policies, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(listener.PolicyNames) != len(policies) {
|
||||||
|
setOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
LoadBalancerPort: aws.Int64(*listener.Listener.LoadBalancerPort),
|
||||||
|
PolicyNames: policies,
|
||||||
|
}
|
||||||
|
|
||||||
|
reassignOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
LoadBalancerPort: aws.Int64(*listener.Listener.LoadBalancerPort),
|
||||||
|
PolicyNames: listener.PolicyNames,
|
||||||
|
}
|
||||||
|
|
||||||
|
reassignments.listenerPolicies = append(reassignments.listenerPolicies, reassignOpts)
|
||||||
|
|
||||||
|
_, err = elbconn.SetLoadBalancerPoliciesOfListener(setOpts)
|
||||||
|
if err != nil {
|
||||||
|
return reassignments, fmt.Errorf("Error Setting Load Balancer Policies of Listener: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reassignments, nil
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/elb"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSLoadBalancerPolicy_basic(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSLoadBalancerPolicyDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerPolicyConfig_basic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-policy"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSLoadBalancerPolicy_updateWhileAssigned(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSLoadBalancerPolicyDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerPolicyConfig_updateWhileAssigned0,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-policy"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSLoadBalancerPolicyConfig_updateWhileAssigned1,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_elb_load_balancer_policy.test-policy"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSLoadBalancerPolicyDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).elbconn
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "aws_elb_load_balancer_policy" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(rs.Primary.ID)
|
||||||
|
out, err := conn.DescribeLoadBalancerPolicies(
|
||||||
|
&elb.DescribeLoadBalancerPoliciesInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
PolicyNames: []*string{aws.String(policyName)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && (ec2err.Code() == "PolicyNotFound" || ec2err.Code() == "LoadBalancerNotFound") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(out.PolicyDescriptions) > 0 {
|
||||||
|
return fmt.Errorf("Policy still exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSLoadBalancerPolicyState(elbResource string, policyResource string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[elbResource]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", elbResource)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
policy, ok := s.RootModule().Resources[policyResource]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", policyResource)
|
||||||
|
}
|
||||||
|
|
||||||
|
elbconn := testAccProvider.Meta().(*AWSClient).elbconn
|
||||||
|
loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(policy.Primary.ID)
|
||||||
|
loadBalancerPolicies, err := elbconn.DescribeLoadBalancerPolicies(&elb.DescribeLoadBalancerPoliciesInput{
|
||||||
|
LoadBalancerName: aws.String(loadBalancerName),
|
||||||
|
PolicyNames: []*string{aws.String(policyName)},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, loadBalancerPolicy := range loadBalancerPolicies.PolicyDescriptions {
|
||||||
|
if *loadBalancerPolicy.PolicyName == policyName {
|
||||||
|
if *loadBalancerPolicy.PolicyTypeName != policy.Primary.Attributes["policy_type_name"] {
|
||||||
|
return fmt.Errorf("PolicyTypeName does not match")
|
||||||
|
}
|
||||||
|
policyAttributeCount, err := strconv.Atoi(policy.Primary.Attributes["policy_attribute.#"])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(loadBalancerPolicy.PolicyAttributeDescriptions) != policyAttributeCount {
|
||||||
|
return fmt.Errorf("PolicyAttributeDescriptions length mismatch")
|
||||||
|
}
|
||||||
|
policyAttributes := make(map[string]string)
|
||||||
|
for k, v := range policy.Primary.Attributes {
|
||||||
|
if strings.HasPrefix(k, "policy_attribute.") && strings.HasSuffix(k, ".name") {
|
||||||
|
key := v
|
||||||
|
value_key := fmt.Sprintf("%s.value", strings.TrimSuffix(k, ".name"))
|
||||||
|
policyAttributes[key] = policy.Primary.Attributes[value_key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, policyAttribute := range loadBalancerPolicy.PolicyAttributeDescriptions {
|
||||||
|
if *policyAttribute.AttributeValue != policyAttributes[*policyAttribute.AttributeName] {
|
||||||
|
return fmt.Errorf("PollicyAttribute Value mismatch %s != %s: %s", *policyAttribute.AttributeValue, policyAttributes[*policyAttribute.AttributeName], policyAttributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerPolicyConfig_basic = `
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 80
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 80
|
||||||
|
lb_protocol = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-policy" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-policy-policy"
|
||||||
|
policy_type_name = "AppCookieStickinessPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "CookieName"
|
||||||
|
value = "magic_cookie"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerPolicyConfig_updateWhileAssigned0 = `
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 80
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 80
|
||||||
|
lb_protocol = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-policy" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-policy-policy"
|
||||||
|
policy_type_name = "AppCookieStickinessPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "CookieName"
|
||||||
|
value = "magic_cookie"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_listener_policy" "test-lb-test-policy-80" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
load_balancer_port = 80
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.test-policy.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAWSLoadBalancerPolicyConfig_updateWhileAssigned1 = `
|
||||||
|
resource "aws_elb" "test-lb" {
|
||||||
|
name = "test-aws-elb-policies-lb"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 80
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 80
|
||||||
|
lb_protocol = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "test-policy" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
policy_name = "test-policy-policy"
|
||||||
|
policy_type_name = "AppCookieStickinessPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "CookieName"
|
||||||
|
value = "unicorn_cookie"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_listener_policy" "test-lb-test-policy-80" {
|
||||||
|
load_balancer_name = "${aws_elb.test-lb.name}"
|
||||||
|
load_balancer_port = 80
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.test-policy.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_elb_load_balancer_backend_server_policy"
|
||||||
|
sidebar_current: "docs-aws-resource-elb-load-balancer-backend-server-policy"
|
||||||
|
description: |-
|
||||||
|
Attaches a load balancer policy to an ELB backend server.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_elb\_load\_balancer\_backend\_server\_policy
|
||||||
|
|
||||||
|
Attaches a load balancer policy to an ELB backend server.
|
||||||
|
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_elb" "wu-tang" {
|
||||||
|
name = "wu-tang"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 443
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 443
|
||||||
|
lb_protocol = "https"
|
||||||
|
ssl_certificate_id = "arn:aws:iam::000000000000:server-certificate/wu-tang.net"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "wu-tang"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "wu-tang-ca-pubkey-policy" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
policy_name = "wu-tang-ca-pubkey-policy"
|
||||||
|
policy_type_name = "PublicKeyPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKey"
|
||||||
|
value = "${file("wu-tang-pubkey")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "wu-tang-root-ca-backend-auth-policy" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
policy_name = "wu-tang-root-ca-backend-auth-policy"
|
||||||
|
policy_type_name = "BackendServerAuthenticationPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKeyPolicyName"
|
||||||
|
value = "${aws_elb_load_balancer_policy.wu-tang-root-ca-pubkey-policy.policy_name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_backend_server_policy" "wu-tang-backend-auth-policies-443" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
instance_port = 443
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.wu-tang-root-ca-backend-auth-policy.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where the file `pubkey` in the current directoy contains only the _public key_ of the certificate.
|
||||||
|
|
||||||
|
```
|
||||||
|
cat wu-tang-ca.pem | openssl x509 -pubkey -noout | grep -v '\-\-\-\-' | tr -d '\n' > wu-tang-pubkey
|
||||||
|
```
|
||||||
|
|
||||||
|
This example shows how to enable backend authentication for an ELB as well as customize the TLS settings.
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `load_balancer_name` - (Required) The load balancer to attach the policy to.
|
||||||
|
* `policy_names` - (Required) List of Policy Names to apply to the backend server.
|
||||||
|
* `instance_port` - (Required) The instance port to apply the policy to.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the policy.
|
||||||
|
* `load_balancer_name` - The load balancer on which the policy is defined.
|
||||||
|
* `instance_port` - The backend port the policies are applied to
|
|
@ -0,0 +1,73 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_elb_load_balancer_listener_policy"
|
||||||
|
sidebar_current: "docs-aws-resource-elb-load-balancer-listener-policy"
|
||||||
|
description: |-
|
||||||
|
Attaches a load balancer policy to an ELB Listener.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_elb\_load\_balancer\_listener\_policy
|
||||||
|
|
||||||
|
Attaches a load balancer policy to an ELB Listener.
|
||||||
|
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_elb" "wu-tang" {
|
||||||
|
name = "wu-tang"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 443
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 443
|
||||||
|
lb_protocol = "https"
|
||||||
|
ssl_certificate_id = "arn:aws:iam::000000000000:server-certificate/wu-tang.net"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "wu-tang"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "wu-tang-ssl" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
policy_name = "wu-tang-ssl"
|
||||||
|
policy_type_name = "SSLNegotiationPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "ECDHE-ECDSA-AES128-GCM-SHA256"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
policy_attribute = {
|
||||||
|
name = "Protocol-TLSv1.2"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_listener_policy" "wu-tang-listener-policies-443" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
load_balancer_port = 443
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.wu-tang-ssl.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This example shows how to customize the TLS settings of an HTTPS listener.
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `load_balancer_name` - (Required) The load balancer to attach the policy to.
|
||||||
|
* `load_balancer_port` - (Required) The load balancer listener port to apply the policy to.
|
||||||
|
* `policy_names` - (Required) List of Policy Names to apply to the backend server.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the policy.
|
||||||
|
* `load_balancer_name` - The load balancer on which the policy is defined.
|
||||||
|
* `load_balancer_port` - The load balancer listener port the policies are applied to
|
|
@ -0,0 +1,108 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_elb_load_balancer_policy"
|
||||||
|
sidebar_current: "docs-aws-resource-elb-load-balancer-policy"
|
||||||
|
description: |-
|
||||||
|
Provides a load balancer policy, which can be attached to an ELB listener or backend server.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_elb\_load\_balancer\_policy
|
||||||
|
|
||||||
|
Provides a load balancer policy, which can be attached to an ELB listener or backend server.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_elb" "wu-tang" {
|
||||||
|
name = "wu-tang"
|
||||||
|
availability_zones = ["us-east-1a"]
|
||||||
|
|
||||||
|
listener {
|
||||||
|
instance_port = 443
|
||||||
|
instance_protocol = "http"
|
||||||
|
lb_port = 443
|
||||||
|
lb_protocol = "https"
|
||||||
|
ssl_certificate_id = "arn:aws:iam::000000000000:server-certificate/wu-tang.net"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "wu-tang"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "wu-tang-ca-pubkey-policy" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
policy_name = "wu-tang-ca-pubkey-policy"
|
||||||
|
policy_type_name = "PublicKeyPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKey"
|
||||||
|
value = "${file("wu-tang-pubkey")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "wu-tang-root-ca-backend-auth-policy" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
policy_name = "wu-tang-root-ca-backend-auth-policy"
|
||||||
|
policy_type_name = "BackendServerAuthenticationPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "PublicKeyPolicyName"
|
||||||
|
value = "${aws_elb_load_balancer_policy.wu-tang-root-ca-pubkey-policy.policy_name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_policy" "wu-tang-ssl" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
policy_name = "wu-tang-ssl"
|
||||||
|
policy_type_name = "SSLNegotiationPolicyType"
|
||||||
|
policy_attribute = {
|
||||||
|
name = "ECDHE-ECDSA-AES128-GCM-SHA256"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
policy_attribute = {
|
||||||
|
name = "Protocol-TLSv1.2"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_backend_server_policy" "wu-tang-backend-auth-policies-443" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
instance_port = 443
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.wu-tang-root-ca-backend-auth-policy.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_elb_load_balancer_listener_policy" "wu-tang-listener-policies-443" {
|
||||||
|
load_balancer_name = "${aws_elb.wu-tang.name}"
|
||||||
|
load_balancer_port = 443
|
||||||
|
policy_names = [
|
||||||
|
"${aws_elb_load_balancer_policy.wu-tang-ssl.policy_name}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where the file `pubkey` in the current directoy contains only the _public key_ of the certificate.
|
||||||
|
|
||||||
|
```
|
||||||
|
cat wu-tang-ca.pem | openssl x509 -pubkey -noout | grep -v '\-\-\-\-' | tr -d '\n' > wu-tang-pubkey
|
||||||
|
```
|
||||||
|
|
||||||
|
This example shows how to enable backend authentication for an ELB as well as customize the TLS settings.
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `load_balancer_name` - (Required) The load balancer on which the policy is defined.
|
||||||
|
* `policy_name` - (Required) The name of the load balancer policy.
|
||||||
|
* `policy_type_name` - (Required) The policy type.
|
||||||
|
* `policy_attribute` - (Optional) Policy attribute to apply to the policy.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the policy.
|
||||||
|
* `policy_name` - The name of the stickiness policy.
|
||||||
|
* `policy_type_name` - The policy type of the policy.
|
||||||
|
* `load_balancer_name` - The load balancer on which the policy is defined.
|
Loading…
Reference in New Issue