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