github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/aws/resource_aws_cloudwatch_event_rule.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "regexp" 7 "time" 8 9 "github.com/aws/aws-sdk-go/aws/awserr" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 13 "github.com/aws/aws-sdk-go/aws" 14 events "github.com/aws/aws-sdk-go/service/cloudwatchevents" 15 ) 16 17 func resourceAwsCloudWatchEventRule() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceAwsCloudWatchEventRuleCreate, 20 Read: resourceAwsCloudWatchEventRuleRead, 21 Update: resourceAwsCloudWatchEventRuleUpdate, 22 Delete: resourceAwsCloudWatchEventRuleDelete, 23 24 Schema: map[string]*schema.Schema{ 25 "name": &schema.Schema{ 26 Type: schema.TypeString, 27 Required: true, 28 ForceNew: true, 29 ValidateFunc: validateCloudWatchEventRuleName, 30 }, 31 "schedule_expression": &schema.Schema{ 32 Type: schema.TypeString, 33 Optional: true, 34 ValidateFunc: validateMaxLength(256), 35 }, 36 "event_pattern": &schema.Schema{ 37 Type: schema.TypeString, 38 Optional: true, 39 ValidateFunc: validateMaxLength(2048), 40 StateFunc: normalizeJson, 41 }, 42 "description": &schema.Schema{ 43 Type: schema.TypeString, 44 Optional: true, 45 ValidateFunc: validateMaxLength(512), 46 }, 47 "role_arn": &schema.Schema{ 48 Type: schema.TypeString, 49 Optional: true, 50 ValidateFunc: validateMaxLength(1600), 51 }, 52 "is_enabled": &schema.Schema{ 53 Type: schema.TypeBool, 54 Optional: true, 55 Default: true, 56 }, 57 "arn": &schema.Schema{ 58 Type: schema.TypeString, 59 Computed: true, 60 }, 61 }, 62 } 63 } 64 65 func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface{}) error { 66 conn := meta.(*AWSClient).cloudwatcheventsconn 67 68 input := buildPutRuleInputStruct(d) 69 log.Printf("[DEBUG] Creating CloudWatch Event Rule: %s", input) 70 71 // IAM Roles take some time to propagate 72 var out *events.PutRuleOutput 73 err := resource.Retry(30*time.Second, func() *resource.RetryError { 74 var err error 75 out, err = conn.PutRule(input) 76 pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$") 77 if err != nil { 78 if awsErr, ok := err.(awserr.Error); ok { 79 if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) { 80 log.Printf("[DEBUG] Retrying creation of CloudWatch Event Rule %q", *input.Name) 81 return resource.RetryableError(err) 82 } 83 } 84 return resource.NonRetryableError(err) 85 } 86 return nil 87 }) 88 if err != nil { 89 return fmt.Errorf("Creating CloudWatch Event Rule failed: %s", err) 90 } 91 92 d.Set("arn", out.RuleArn) 93 d.SetId(d.Get("name").(string)) 94 95 log.Printf("[INFO] CloudWatch Event Rule %q created", *out.RuleArn) 96 97 return resourceAwsCloudWatchEventRuleUpdate(d, meta) 98 } 99 100 func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{}) error { 101 conn := meta.(*AWSClient).cloudwatcheventsconn 102 103 input := events.DescribeRuleInput{ 104 Name: aws.String(d.Id()), 105 } 106 log.Printf("[DEBUG] Reading CloudWatch Event Rule: %s", input) 107 out, err := conn.DescribeRule(&input) 108 if awsErr, ok := err.(awserr.Error); ok { 109 if awsErr.Code() == "ResourceNotFoundException" { 110 log.Printf("[WARN] Removing CloudWatch Event Rule %q because it's gone.", d.Id()) 111 d.SetId("") 112 return nil 113 } 114 } 115 if err != nil { 116 return err 117 } 118 log.Printf("[DEBUG] Found Event Rule: %s", out) 119 120 d.Set("arn", out.Arn) 121 d.Set("description", out.Description) 122 if out.EventPattern != nil { 123 d.Set("event_pattern", normalizeJson(*out.EventPattern)) 124 } 125 d.Set("name", out.Name) 126 d.Set("role_arn", out.RoleArn) 127 d.Set("schedule_expression", out.ScheduleExpression) 128 129 boolState, err := getBooleanStateFromString(*out.State) 130 if err != nil { 131 return err 132 } 133 log.Printf("[DEBUG] Setting boolean state: %t", boolState) 134 d.Set("is_enabled", boolState) 135 136 return nil 137 } 138 139 func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface{}) error { 140 conn := meta.(*AWSClient).cloudwatcheventsconn 141 142 if d.HasChange("is_enabled") && d.Get("is_enabled").(bool) { 143 log.Printf("[DEBUG] Enabling CloudWatch Event Rule %q", d.Id()) 144 _, err := conn.EnableRule(&events.EnableRuleInput{ 145 Name: aws.String(d.Id()), 146 }) 147 if err != nil { 148 return err 149 } 150 log.Printf("[DEBUG] CloudWatch Event Rule (%q) enabled", d.Id()) 151 } 152 153 input := buildPutRuleInputStruct(d) 154 log.Printf("[DEBUG] Updating CloudWatch Event Rule: %s", input) 155 156 // IAM Roles take some time to propagate 157 var out *events.PutRuleOutput 158 err := resource.Retry(30*time.Second, func() *resource.RetryError { 159 var err error 160 out, err = conn.PutRule(input) 161 pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$") 162 if err != nil { 163 if awsErr, ok := err.(awserr.Error); ok { 164 if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) { 165 log.Printf("[DEBUG] Retrying update of CloudWatch Event Rule %q", *input.Name) 166 return resource.RetryableError(err) 167 } 168 } 169 return resource.NonRetryableError(err) 170 } 171 return nil 172 }) 173 if err != nil { 174 return fmt.Errorf("Updating CloudWatch Event Rule failed: %s", err) 175 } 176 177 if d.HasChange("is_enabled") && !d.Get("is_enabled").(bool) { 178 log.Printf("[DEBUG] Disabling CloudWatch Event Rule %q", d.Id()) 179 _, err := conn.DisableRule(&events.DisableRuleInput{ 180 Name: aws.String(d.Id()), 181 }) 182 if err != nil { 183 return err 184 } 185 log.Printf("[DEBUG] CloudWatch Event Rule (%q) disabled", d.Id()) 186 } 187 188 return resourceAwsCloudWatchEventRuleRead(d, meta) 189 } 190 191 func resourceAwsCloudWatchEventRuleDelete(d *schema.ResourceData, meta interface{}) error { 192 conn := meta.(*AWSClient).cloudwatcheventsconn 193 194 log.Printf("[INFO] Deleting CloudWatch Event Rule: %s", d.Id()) 195 _, err := conn.DeleteRule(&events.DeleteRuleInput{ 196 Name: aws.String(d.Id()), 197 }) 198 if err != nil { 199 return fmt.Errorf("Error deleting CloudWatch Event Rule: %s", err) 200 } 201 log.Println("[INFO] CloudWatch Event Rule deleted") 202 203 d.SetId("") 204 205 return nil 206 } 207 208 func buildPutRuleInputStruct(d *schema.ResourceData) *events.PutRuleInput { 209 input := events.PutRuleInput{ 210 Name: aws.String(d.Get("name").(string)), 211 } 212 if v, ok := d.GetOk("description"); ok { 213 input.Description = aws.String(v.(string)) 214 } 215 if v, ok := d.GetOk("event_pattern"); ok { 216 input.EventPattern = aws.String(normalizeJson(v.(string))) 217 } 218 if v, ok := d.GetOk("role_arn"); ok { 219 input.RoleArn = aws.String(v.(string)) 220 } 221 if v, ok := d.GetOk("schedule_expression"); ok { 222 input.ScheduleExpression = aws.String(v.(string)) 223 } 224 225 input.State = aws.String(getStringStateFromBoolean(d.Get("is_enabled").(bool))) 226 227 return &input 228 } 229 230 // State is represented as (ENABLED|DISABLED) in the API 231 func getBooleanStateFromString(state string) (bool, error) { 232 if state == "ENABLED" { 233 return true, nil 234 } else if state == "DISABLED" { 235 return false, nil 236 } 237 // We don't just blindly trust AWS as they tend to return 238 // unexpected values in similar cases (different casing etc.) 239 return false, fmt.Errorf("Failed converting state %q into boolean", state) 240 } 241 242 // State is represented as (ENABLED|DISABLED) in the API 243 func getStringStateFromBoolean(isEnabled bool) string { 244 if isEnabled { 245 return "ENABLED" 246 } 247 return "DISABLED" 248 }