github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/builtin/providers/aws/resource_aws_sns_topic_subscription.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/hashicorp/terraform/helper/schema" 9 10 "github.com/aws/aws-sdk-go/aws" 11 "github.com/aws/aws-sdk-go/service/sns" 12 ) 13 14 const awsSNSPendingConfirmationMessage = "pending confirmation" 15 16 func resourceAwsSnsTopicSubscription() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceAwsSnsTopicSubscriptionCreate, 19 Read: resourceAwsSnsTopicSubscriptionRead, 20 Update: resourceAwsSnsTopicSubscriptionUpdate, 21 Delete: resourceAwsSnsTopicSubscriptionDelete, 22 23 Schema: map[string]*schema.Schema{ 24 "protocol": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: false, 28 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 29 value := v.(string) 30 forbidden := []string{"email", "sms", "http"} 31 for _, f := range forbidden { 32 if strings.Contains(value, f) { 33 errors = append( 34 errors, 35 fmt.Errorf("Unsupported protocol (%s) for SNS Topic", value), 36 ) 37 } 38 } 39 return 40 }, 41 }, 42 "endpoint": &schema.Schema{ 43 Type: schema.TypeString, 44 Required: true, 45 ForceNew: false, 46 }, 47 "topic_arn": &schema.Schema{ 48 Type: schema.TypeString, 49 Required: true, 50 ForceNew: false, 51 }, 52 "delivery_policy": &schema.Schema{ 53 Type: schema.TypeString, 54 Optional: true, 55 ForceNew: false, 56 }, 57 "raw_message_delivery": &schema.Schema{ 58 Type: schema.TypeBool, 59 Optional: true, 60 ForceNew: false, 61 Default: false, 62 }, 63 "arn": &schema.Schema{ 64 Type: schema.TypeString, 65 Computed: true, 66 }, 67 }, 68 } 69 } 70 71 func resourceAwsSnsTopicSubscriptionCreate(d *schema.ResourceData, meta interface{}) error { 72 snsconn := meta.(*AWSClient).snsconn 73 74 output, err := subscribeToSNSTopic(d, snsconn) 75 76 if err != nil { 77 return err 78 } 79 80 if output.SubscriptionArn != nil && *output.SubscriptionArn == awsSNSPendingConfirmationMessage { 81 log.Printf("[WARN] Invalid SNS Subscription, received a \"%s\" ARN", awsSNSPendingConfirmationMessage) 82 return nil 83 } 84 85 log.Printf("New subscription ARN: %s", *output.SubscriptionArn) 86 d.SetId(*output.SubscriptionArn) 87 88 // Write the ARN to the 'arn' field for export 89 d.Set("arn", *output.SubscriptionArn) 90 91 return resourceAwsSnsTopicSubscriptionUpdate(d, meta) 92 } 93 94 func resourceAwsSnsTopicSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error { 95 snsconn := meta.(*AWSClient).snsconn 96 97 // If any changes happened, un-subscribe and re-subscribe 98 if d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn") { 99 log.Printf("[DEBUG] Updating subscription %s", d.Id()) 100 // Unsubscribe 101 _, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{ 102 SubscriptionArn: aws.String(d.Id()), 103 }) 104 105 if err != nil { 106 return fmt.Errorf("Error unsubscribing from SNS topic: %s", err) 107 } 108 109 // Re-subscribe and set id 110 output, err := subscribeToSNSTopic(d, snsconn) 111 d.SetId(*output.SubscriptionArn) 112 d.Set("arn", *output.SubscriptionArn) 113 } 114 115 if d.HasChange("raw_message_delivery") { 116 _, n := d.GetChange("raw_message_delivery") 117 118 attrValue := "false" 119 120 if n.(bool) { 121 attrValue = "true" 122 } 123 124 req := &sns.SetSubscriptionAttributesInput{ 125 SubscriptionArn: aws.String(d.Id()), 126 AttributeName: aws.String("RawMessageDelivery"), 127 AttributeValue: aws.String(attrValue), 128 } 129 _, err := snsconn.SetSubscriptionAttributes(req) 130 131 if err != nil { 132 return fmt.Errorf("Unable to set raw message delivery attribute on subscription") 133 } 134 } 135 136 return resourceAwsSnsTopicSubscriptionRead(d, meta) 137 } 138 139 func resourceAwsSnsTopicSubscriptionRead(d *schema.ResourceData, meta interface{}) error { 140 snsconn := meta.(*AWSClient).snsconn 141 142 log.Printf("[DEBUG] Loading subscription %s", d.Id()) 143 144 attributeOutput, err := snsconn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{ 145 SubscriptionArn: aws.String(d.Id()), 146 }) 147 if err != nil { 148 return err 149 } 150 151 if attributeOutput.Attributes != nil && len(attributeOutput.Attributes) > 0 { 152 attrHash := attributeOutput.Attributes 153 log.Printf("[DEBUG] raw message delivery: %s", *attrHash["RawMessageDelivery"]) 154 if *attrHash["RawMessageDelivery"] == "true" { 155 d.Set("raw_message_delivery", true) 156 } else { 157 d.Set("raw_message_delivery", false) 158 } 159 } 160 161 return nil 162 } 163 164 func resourceAwsSnsTopicSubscriptionDelete(d *schema.ResourceData, meta interface{}) error { 165 snsconn := meta.(*AWSClient).snsconn 166 167 log.Printf("[DEBUG] SNS delete topic subscription: %s", d.Id()) 168 _, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{ 169 SubscriptionArn: aws.String(d.Id()), 170 }) 171 if err != nil { 172 return err 173 } 174 return nil 175 } 176 177 func subscribeToSNSTopic(d *schema.ResourceData, snsconn *sns.SNS) (output *sns.SubscribeOutput, err error) { 178 protocol := d.Get("protocol").(string) 179 endpoint := d.Get("endpoint").(string) 180 topic_arn := d.Get("topic_arn").(string) 181 182 log.Printf("[DEBUG] SNS create topic subscription: %s (%s) @ '%s'", endpoint, protocol, topic_arn) 183 184 req := &sns.SubscribeInput{ 185 Protocol: aws.String(protocol), 186 Endpoint: aws.String(endpoint), 187 TopicArn: aws.String(topic_arn), 188 } 189 190 output, err = snsconn.Subscribe(req) 191 if err != nil { 192 return nil, fmt.Errorf("Error creating SNS topic: %s", err) 193 } 194 195 log.Printf("[DEBUG] Created new subscription!") 196 return output, nil 197 }