Merge branch 'ewdurbin-elb_backend_auth'

This commit is contained in:
stack72 2016-08-09 15:13:08 +12:00
commit f5714ab5a9
No known key found for this signature in database
GPG Key ID: 8619A619B085CB16
13 changed files with 1882 additions and 0 deletions

View File

@ -219,6 +219,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_load_balancer_policy": resourceAwsLoadBalancerPolicy(),
"aws_load_balancer_backend_server_policy": resourceAwsLoadBalancerBackendServerPolicies(),
"aws_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(),

View File

@ -0,0 +1,138 @@
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)))
return resourceAwsLoadBalancerBackendServerPoliciesRead(d, meta)
}
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" {
d.SetId("")
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)
}
d.SetId("")
return nil
}
func resourceAwsLoadBalancerBackendServerPoliciesParseId(id string) (string, string) {
parts := strings.SplitN(id, ":", 2)
return parts[0], parts[1]
}

View File

@ -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_load_balancer_policy.test-pubkey-policy0"),
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_load_balancer_policy.test-backend-auth-policy0"),
testAccCheckAWSLoadBalancerBackendServerPolicyState("test-aws-policies-lb", "test-backend-auth-policy0", true),
),
},
resource.TestStep{
Config: testAccAWSLoadBalancerBackendServerPolicyConfig_basic1,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_load_balancer_policy.test-pubkey-policy0"),
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_load_balancer_policy.test-pubkey-policy1"),
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_load_balancer_policy.test-backend-auth-policy0"),
testAccCheckAWSLoadBalancerBackendServerPolicyState("test-aws-policies-lb", "test-backend-auth-policy0", true),
),
},
resource.TestStep{
Config: testAccAWSLoadBalancerBackendServerPolicyConfig_basic2,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSLoadBalancerBackendServerPolicyState("test-aws-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_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_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-policies-lb"
availability_zones = ["us-west-2a"]
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_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_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_load_balancer_policy.test-pubkey-policy0.policy_name}"
}
}
resource "aws_load_balancer_backend_server_policy" "test-backend-auth-policies-443" {
load_balancer_name = "${aws_elb.test-lb.name}"
instance_port = 443
policy_names = [
"${aws_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-policies-lb"
availability_zones = ["us-west-2a"]
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_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_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_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_load_balancer_policy.test-pubkey-policy1.policy_name}"
}
}
resource "aws_load_balancer_backend_server_policy" "test-backend-auth-policies-443" {
load_balancer_name = "${aws_elb.test-lb.name}"
instance_port = 443
policy_names = [
"${aws_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-policies-lb"
availability_zones = ["us-west-2a"]
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"
}
}
`

View File

@ -0,0 +1,138 @@
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)))
return resourceAwsLoadBalancerListenerPoliciesRead(d, meta)
}
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" {
d.SetId("")
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)
}
d.SetId("")
return nil
}
func resourceAwsLoadBalancerListenerPoliciesParseId(id string) (string, string) {
parts := strings.SplitN(id, ":", 2)
return parts[0], parts[1]
}

View File

@ -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_load_balancer_policy.magic-cookie-sticky"),
testAccCheckAWSLoadBalancerListenerPolicyState("test-aws-policies-lb", int64(80), "magic-cookie-sticky-policy", true),
),
},
resource.TestStep{
Config: testAccAWSLoadBalancerListenerPolicyConfig_basic1,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_load_balancer_policy.magic-cookie-sticky"),
testAccCheckAWSLoadBalancerListenerPolicyState("test-aws-policies-lb", int64(80), "magic-cookie-sticky-policy", true),
),
},
resource.TestStep{
Config: testAccAWSLoadBalancerListenerPolicyConfig_basic2,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSLoadBalancerListenerPolicyState("test-aws-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_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_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-policies-lb"
availability_zones = ["us-west-2a"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
tags {
Name = "tf-acc-test"
}
}
resource "aws_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_load_balancer_listener_policy" "test-lb-listener-policies-80" {
load_balancer_name = "${aws_elb.test-lb.name}"
load_balancer_port = 80
policy_names = [
"${aws_load_balancer_policy.magic-cookie-sticky.policy_name}",
]
}
`
const testAccAWSLoadBalancerListenerPolicyConfig_basic1 = `
resource "aws_elb" "test-lb" {
name = "test-aws-policies-lb"
availability_zones = ["us-west-2a"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
tags {
Name = "tf-acc-test"
}
}
resource "aws_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_load_balancer_listener_policy" "test-lb-listener-policies-80" {
load_balancer_name = "${aws_elb.test-lb.name}"
load_balancer_port = 80
policy_names = [
"${aws_load_balancer_policy.magic-cookie-sticky.policy_name}"
]
}
`
const testAccAWSLoadBalancerListenerPolicyConfig_basic2 = `
resource "aws_elb" "test-lb" {
name = "test-aws-policies-lb"
availability_zones = ["us-west-2a"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
tags {
Name = "tf-acc-test"
}
}
`

View File

@ -0,0 +1,352 @@
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 resourceAwsLoadBalancerPolicyRead(d, meta)
}
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 resourceAwsLoadBalancerPolicyRead(d, meta)
}
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)
}
d.SetId("")
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
}

View File

@ -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_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_load_balancer_policy.test-policy"),
),
},
resource.TestStep{
Config: testAccAWSLoadBalancerPolicyConfig_updateWhileAssigned1,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSLoadBalancerPolicyState("aws_elb.test-lb", "aws_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_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-policies-lb"
availability_zones = ["us-west-2a"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
tags {
Name = "tf-acc-test"
}
}
resource "aws_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-policies-lb"
availability_zones = ["us-west-2a"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
tags {
Name = "tf-acc-test"
}
}
resource "aws_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_load_balancer_listener_policy" "test-lb-test-policy-80" {
load_balancer_name = "${aws_elb.test-lb.name}"
load_balancer_port = 80
policy_names = [
"${aws_load_balancer_policy.test-policy.policy_name}"
]
}
`
const testAccAWSLoadBalancerPolicyConfig_updateWhileAssigned1 = `
resource "aws_elb" "test-lb" {
name = "test-aws-policies-lb"
availability_zones = ["us-west-2a"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
tags {
Name = "tf-acc-test"
}
}
resource "aws_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_load_balancer_listener_policy" "test-lb-test-policy-80" {
load_balancer_name = "${aws_elb.test-lb.name}"
load_balancer_port = 80
policy_names = [
"${aws_load_balancer_policy.test-policy.policy_name}"
]
}
`

View File

@ -97,6 +97,18 @@ func resourceAwsRDSClusterInstance() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
"monitoring_role_arn": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"monitoring_interval": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 0,
},
"tags": tagsSchema(), "tags": tagsSchema(),
}, },
} }
@ -128,6 +140,14 @@ func resourceAwsRDSClusterInstanceCreate(d *schema.ResourceData, meta interface{
createOpts.DBSubnetGroupName = aws.String(attr.(string)) createOpts.DBSubnetGroupName = aws.String(attr.(string))
} }
if attr, ok := d.GetOk("monitoring_role_arn"); ok {
createOpts.MonitoringRoleArn = aws.String(attr.(string))
}
if attr, ok := d.GetOk("monitoring_interval"); ok {
createOpts.MonitoringInterval = aws.Int64(int64(attr.(int)))
}
log.Printf("[DEBUG] Creating RDS DB Instance opts: %s", createOpts) log.Printf("[DEBUG] Creating RDS DB Instance opts: %s", createOpts)
resp, err := conn.CreateDBInstance(createOpts) resp, err := conn.CreateDBInstance(createOpts)
if err != nil { if err != nil {
@ -207,6 +227,14 @@ func resourceAwsRDSClusterInstanceRead(d *schema.ResourceData, meta interface{})
d.Set("identifier", db.DBInstanceIdentifier) d.Set("identifier", db.DBInstanceIdentifier)
d.Set("storage_encrypted", db.StorageEncrypted) d.Set("storage_encrypted", db.StorageEncrypted)
if db.MonitoringInterval != nil {
d.Set("monitoring_interval", db.MonitoringInterval)
}
if db.MonitoringRoleArn != nil {
d.Set("monitoring_role_arn", db.MonitoringRoleArn)
}
if len(db.DBParameterGroups) > 0 { if len(db.DBParameterGroups) > 0 {
d.Set("db_parameter_group_name", db.DBParameterGroups[0].DBParameterGroupName) d.Set("db_parameter_group_name", db.DBParameterGroups[0].DBParameterGroupName)
} }
@ -245,6 +273,18 @@ func resourceAwsRDSClusterInstanceUpdate(d *schema.ResourceData, meta interface{
} }
if d.HasChange("monitoring_role_arn") {
d.SetPartial("monitoring_role_arn")
req.MonitoringRoleArn = aws.String(d.Get("monitoring_role_arn").(string))
requestUpdate = true
}
if d.HasChange("monitoring_interval") {
d.SetPartial("monitoring_interval")
req.MonitoringInterval = aws.Int64(int64(d.Get("monitoring_interval").(int)))
requestUpdate = true
}
log.Printf("[DEBUG] Send DB Instance Modification request: %#v", requestUpdate) log.Printf("[DEBUG] Send DB Instance Modification request: %#v", requestUpdate)
if requestUpdate { if requestUpdate {
log.Printf("[DEBUG] DB Instance Modification request: %#v", req) log.Printf("[DEBUG] DB Instance Modification request: %#v", req)

View File

@ -187,6 +187,25 @@ func testAccCheckAWSClusterInstanceExists(n string, v *rds.DBInstance) resource.
} }
} }
func TestAccAWSCluster_withInstanceEnhancedMonitor(t *testing.T) {
var v rds.DBInstance
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSClusterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSClusterInstanceEnhancedMonitor(acctest.RandInt()),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSClusterInstanceExists("aws_rds_cluster_instance.cluster_instances", &v),
testAccCheckAWSDBClusterInstanceAttributes(&v),
),
},
},
})
}
// Add some random to the name, to avoid collision // Add some random to the name, to avoid collision
func testAccAWSClusterInstanceConfig(n int) string { func testAccAWSClusterInstanceConfig(n int) string {
return fmt.Sprintf(` return fmt.Sprintf(`
@ -281,3 +300,64 @@ resource "aws_db_parameter_group" "bar" {
} }
`, n, n, n, n) `, n, n, n, n)
} }
func testAccAWSClusterInstanceEnhancedMonitor(n int) string {
return fmt.Sprintf(`
resource "aws_rds_cluster" "default" {
cluster_identifier = "tf-aurora-cluster-test-%d"
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
database_name = "mydb"
master_username = "foo"
master_password = "mustbeeightcharaters"
}
resource "aws_rds_cluster_instance" "cluster_instances" {
identifier = "tf-cluster-instance-%d"
cluster_identifier = "${aws_rds_cluster.default.id}"
instance_class = "db.r3.large"
db_parameter_group_name = "${aws_db_parameter_group.bar.name}"
monitoring_interval = "60"
monitoring_role_arn = "${aws_iam_role.tf_enhanced_monitor_role.arn}"
}
resource "aws_iam_role" "tf_enhanced_monitor_role" {
name = "tf_enhanced_monitor_role-%d"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "monitoring.rds.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy_attachment" "rds_m_attach" {
name = "AmazonRDSEnhancedMonitoringRole"
roles = ["${aws_iam_role.tf_enhanced_monitor_role.name}"]
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"
}
resource "aws_db_parameter_group" "bar" {
name = "tfcluster-test-group-%d"
family = "aurora5.6"
parameter {
name = "back_log"
value = "32767"
apply_method = "pending-reboot"
}
tags {
foo = "bar"
}
}
`, n, n, n, n)
}

View File

@ -0,0 +1,85 @@
---
layout: "aws"
page_title: "AWS: aws_load_balancer_backend_server_policy"
sidebar_current: "docs-aws-resource-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_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_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_load_balancer_policy.wu-tang-root-ca-pubkey-policy.policy_name}"
}
}
resource "aws_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_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

View File

@ -0,0 +1,73 @@
---
layout: "aws"
page_title: "AWS: aws_load_balancer_listener_policy"
sidebar_current: "docs-aws-resource-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_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_load_balancer_listener_policy" "wu-tang-listener-policies-443" {
load_balancer_name = "${aws_elb.wu-tang.name}"
load_balancer_port = 443
policy_names = [
"${aws_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

View File

@ -0,0 +1,108 @@
---
layout: "aws"
page_title: "AWS: aws_load_balancer_policy"
sidebar_current: "docs-aws-resource-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_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_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_load_balancer_policy.wu-tang-root-ca-pubkey-policy.policy_name}"
}
}
resource "aws_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_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_load_balancer_policy.wu-tang-root-ca-backend-auth-policy.policy_name}"
]
}
resource "aws_load_balancer_listener_policy" "wu-tang-listener-policies-443" {
load_balancer_name = "${aws_elb.wu-tang.name}"
load_balancer_port = 443
policy_names = [
"${aws_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.

View File

@ -66,6 +66,10 @@ details on controlling this property.
* `apply_immediately` - (Optional) Specifies whether any database modifications * `apply_immediately` - (Optional) Specifies whether any database modifications
are applied immediately, or during the next maintenance window. Default is`false`. are applied immediately, or during the next maintenance window. Default is`false`.
* `storage_encrypted` - (Optional) Specifies whether the DB cluster instance is encrypted. The default is `false` if not specified. * `storage_encrypted` - (Optional) Specifies whether the DB cluster instance is encrypted. The default is `false` if not specified.
* `monitoring_role_arn` - (Optional) The ARN for the IAM role that permits RDS to send
enhanced monitoring metrics to CloudWatch Logs. You can find more information on the [AWS Documentation](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.html)
what IAM permissions are needed to allow Enhanced Monitoring for RDS Instances.
* `monitoring_interval` - (Optional) The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. The default is 0. Valid Values: 0, 1, 5, 10, 15, 30, 60.
* `kms_key_id` - (Optional) The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to true * `kms_key_id` - (Optional) The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to true
* `tags` - (Optional) A mapping of tags to assign to the instance. * `tags` - (Optional) A mapping of tags to assign to the instance.