github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_lb_cookie_stickiness_policy.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/awserr" 10 "github.com/aws/aws-sdk-go/service/elb" 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceAwsLBCookieStickinessPolicy() *schema.Resource { 15 return &schema.Resource{ 16 // There is no concept of "updating" an LB Stickiness policy in 17 // the AWS API. 18 Create: resourceAwsLBCookieStickinessPolicyCreate, 19 Read: resourceAwsLBCookieStickinessPolicyRead, 20 Delete: resourceAwsLBCookieStickinessPolicyDelete, 21 22 Schema: map[string]*schema.Schema{ 23 "name": &schema.Schema{ 24 Type: schema.TypeString, 25 Required: true, 26 ForceNew: true, 27 }, 28 29 "load_balancer": &schema.Schema{ 30 Type: schema.TypeString, 31 Required: true, 32 ForceNew: true, 33 }, 34 35 "lb_port": &schema.Schema{ 36 Type: schema.TypeInt, 37 Required: true, 38 ForceNew: true, 39 }, 40 41 "cookie_expiration_period": &schema.Schema{ 42 Type: schema.TypeInt, 43 Optional: true, 44 ForceNew: true, 45 ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { 46 value := v.(int) 47 if value <= 0 { 48 es = append(es, fmt.Errorf( 49 "LB Cookie Expiration Period must be greater than zero if specified")) 50 } 51 return 52 }, 53 }, 54 }, 55 } 56 } 57 58 func resourceAwsLBCookieStickinessPolicyCreate(d *schema.ResourceData, meta interface{}) error { 59 elbconn := meta.(*AWSClient).elbconn 60 61 // Provision the LBStickinessPolicy 62 lbspOpts := &elb.CreateLBCookieStickinessPolicyInput{ 63 LoadBalancerName: aws.String(d.Get("load_balancer").(string)), 64 PolicyName: aws.String(d.Get("name").(string)), 65 } 66 67 if v := d.Get("cookie_expiration_period").(int); v > 0 { 68 lbspOpts.CookieExpirationPeriod = aws.Int64(int64(v)) 69 } 70 71 log.Printf("[DEBUG] LB Cookie Stickiness Policy opts: %#v", lbspOpts) 72 if _, err := elbconn.CreateLBCookieStickinessPolicy(lbspOpts); err != nil { 73 return fmt.Errorf("Error creating LBCookieStickinessPolicy: %s", err) 74 } 75 76 setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ 77 LoadBalancerName: aws.String(d.Get("load_balancer").(string)), 78 LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), 79 PolicyNames: []*string{aws.String(d.Get("name").(string))}, 80 } 81 82 log.Printf("[DEBUG] LB Cookie Stickiness create configuration: %#v", setLoadBalancerOpts) 83 if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil { 84 return fmt.Errorf("Error setting LBCookieStickinessPolicy: %s", err) 85 } 86 87 d.SetId(fmt.Sprintf("%s:%d:%s", 88 *lbspOpts.LoadBalancerName, 89 *setLoadBalancerOpts.LoadBalancerPort, 90 *lbspOpts.PolicyName)) 91 return nil 92 } 93 94 func resourceAwsLBCookieStickinessPolicyRead(d *schema.ResourceData, meta interface{}) error { 95 elbconn := meta.(*AWSClient).elbconn 96 97 lbName, lbPort, policyName := resourceAwsLBCookieStickinessPolicyParseId(d.Id()) 98 99 request := &elb.DescribeLoadBalancerPoliciesInput{ 100 LoadBalancerName: aws.String(lbName), 101 PolicyNames: []*string{aws.String(policyName)}, 102 } 103 104 getResp, err := elbconn.DescribeLoadBalancerPolicies(request) 105 if err != nil { 106 if ec2err, ok := err.(awserr.Error); ok { 107 if ec2err.Code() == "PolicyNotFound" || ec2err.Code() == "LoadBalancerNotFound" { 108 d.SetId("") 109 } 110 return nil 111 } 112 return fmt.Errorf("Error retrieving policy: %s", err) 113 } 114 115 if len(getResp.PolicyDescriptions) != 1 { 116 return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions) 117 } 118 119 // we know the policy exists now, but we have to check if it's assigned to a listener 120 assigned, err := resourceAwsELBSticknessPolicyAssigned(policyName, lbName, lbPort, elbconn) 121 if err != nil { 122 return err 123 } 124 if !assigned { 125 // policy exists, but isn't assigned to a listener 126 log.Printf("[DEBUG] policy '%s' exists, but isn't assigned to a listener", policyName) 127 d.SetId("") 128 return nil 129 } 130 131 // We can get away with this because there's only one attribute, the 132 // cookie expiration, in these descriptions. 133 policyDesc := getResp.PolicyDescriptions[0] 134 cookieAttr := policyDesc.PolicyAttributeDescriptions[0] 135 if *cookieAttr.AttributeName != "CookieExpirationPeriod" { 136 return fmt.Errorf("Unable to find cookie expiration period.") 137 } 138 d.Set("cookie_expiration_period", cookieAttr.AttributeValue) 139 140 d.Set("name", policyName) 141 d.Set("load_balancer", lbName) 142 d.Set("lb_port", lbPort) 143 144 return nil 145 } 146 147 func resourceAwsLBCookieStickinessPolicyDelete(d *schema.ResourceData, meta interface{}) error { 148 elbconn := meta.(*AWSClient).elbconn 149 150 lbName, _, policyName := resourceAwsLBCookieStickinessPolicyParseId(d.Id()) 151 152 // Perversely, if we Set an empty list of PolicyNames, we detach the 153 // policies attached to a listener, which is required to delete the 154 // policy itself. 155 setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ 156 LoadBalancerName: aws.String(d.Get("load_balancer").(string)), 157 LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), 158 PolicyNames: []*string{}, 159 } 160 161 if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil { 162 return fmt.Errorf("Error removing LBCookieStickinessPolicy: %s", err) 163 } 164 165 request := &elb.DeleteLoadBalancerPolicyInput{ 166 LoadBalancerName: aws.String(lbName), 167 PolicyName: aws.String(policyName), 168 } 169 170 if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil { 171 return fmt.Errorf("Error deleting LB stickiness policy %s: %s", d.Id(), err) 172 } 173 return nil 174 } 175 176 // resourceAwsLBCookieStickinessPolicyParseId takes an ID and parses it into 177 // it's constituent parts. You need three axes (LB name, policy name, and LB 178 // port) to create or identify a stickiness policy in AWS's API. 179 func resourceAwsLBCookieStickinessPolicyParseId(id string) (string, string, string) { 180 parts := strings.SplitN(id, ":", 3) 181 return parts[0], parts[1], parts[2] 182 }