diff --git a/aws/resource_aws_cloudwatch_event_rule.go b/aws/resource_aws_cloudwatch_event_rule.go index 62a58bfc86d..bb3e7db61d7 100644 --- a/aws/resource_aws_cloudwatch_event_rule.go +++ b/aws/resource_aws_cloudwatch_event_rule.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "log" + "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -26,7 +27,7 @@ func resourceAwsCloudWatchEventRule() *schema.Resource { Update: resourceAwsCloudWatchEventRuleUpdate, Delete: resourceAwsCloudWatchEventRuleDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceAwsCloudWatchEventRuleImport, }, Schema: map[string]*schema.Schema{ @@ -49,6 +50,20 @@ func resourceAwsCloudWatchEventRule() *schema.Resource { Optional: true, ValidateFunc: validation.StringLenBetween(0, 256), }, + "event_bus_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 256), + StateFunc: func(v interface{}) string { + if v.(string) == "default" { + // "default" event bus name is not stored in the state to support the case when event_bus_name is omitted + return "" + } + + return v.(string) + }, + }, "event_pattern": { Type: schema.TypeString, Optional: true, @@ -123,7 +138,12 @@ func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface } d.Set("arn", out.RuleArn) - d.SetId(*input.Name) + id := aws.StringValue(input.Name) + eventBusName := aws.StringValue(input.EventBusName) + if eventBusName != "" && eventBusName != "default" { + id = eventBusName + "/" + id + } + d.SetId(id) log.Printf("[INFO] CloudWatch Event Rule %q created", *out.RuleArn) @@ -132,9 +152,13 @@ func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - + busName, ruleName, err := determineCloudwatchEventBusNameAndEventRuleNameFromRuleId(d.Id()) + if err != nil { + return err + } input := events.DescribeRuleInput{ - Name: aws.String(d.Id()), + Name: aws.String(ruleName), + EventBusName: aws.String(busName), } log.Printf("[DEBUG] Reading CloudWatch Event Rule: %s", input) out, err := conn.DescribeRule(&input) @@ -163,6 +187,9 @@ func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{} d.Set("name", out.Name) d.Set("role_arn", out.RoleArn) d.Set("schedule_expression", out.ScheduleExpression) + if aws.StringValue(out.EventBusName) != "default" { + d.Set("event_bus_name", out.EventBusName) + } boolState, err := getBooleanStateFromString(*out.State) if err != nil { @@ -186,8 +213,11 @@ func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{} func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - - input, err := buildPutRuleInputStruct(d, d.Id()) + _, ruleName, err := determineCloudwatchEventBusNameAndEventRuleNameFromRuleId(d.Id()) + if err != nil { + return err + } + input, err := buildPutRuleInputStruct(d, ruleName) if err != nil { return fmt.Errorf("Updating CloudWatch Event Rule failed: %s", err) } @@ -228,12 +258,16 @@ func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface func resourceAwsCloudWatchEventRuleDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - + busName, ruleName, err := determineCloudwatchEventBusNameAndEventRuleNameFromRuleId(d.Id()) + if err != nil { + return err + } input := &events.DeleteRuleInput{ - Name: aws.String(d.Id()), + Name: aws.String(ruleName), + EventBusName: aws.String(busName), } - err := resource.Retry(cloudWatchEventRuleDeleteRetryTimeout, func() *resource.RetryError { + err = resource.Retry(cloudWatchEventRuleDeleteRetryTimeout, func() *resource.RetryError { _, err := conn.DeleteRule(input) if isAWSErr(err, "ValidationException", "Rule can't be deleted since it has targets") { @@ -265,6 +299,9 @@ func buildPutRuleInputStruct(d *schema.ResourceData, name string) (*events.PutRu if v, ok := d.GetOk("description"); ok { input.Description = aws.String(v.(string)) } + if v, ok := d.GetOk("event_bus_name"); ok { + input.EventBusName = aws.String(v.(string)) + } if v, ok := d.GetOk("event_pattern"); ok { pattern, err := structure.NormalizeJsonString(v) if err != nil { @@ -328,3 +365,32 @@ func validateEventPatternValue() schema.SchemaValidateFunc { return } } + +func determineCloudwatchEventBusNameAndEventRuleNameFromRuleId(id string) (string, string, error) { + splitId := strings.Split(id, "/") + busName := "default" + var ruleName string + if len(splitId) > 2 { + return busName, ruleName, fmt.Errorf("wrong format of resource: %s. Please follow / or ", id) + } else if len(splitId) == 2 { + busName = splitId[0] + ruleName = splitId[1] + } else { + ruleName = splitId[0] + } + + return busName, ruleName, nil +} + +func resourceAwsCloudWatchEventRuleImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + busName, ruleName, err := determineCloudwatchEventBusNameAndEventRuleNameFromRuleId(d.Id()) + if err != nil { + return []*schema.ResourceData{}, err + } + if busName != "default" { + d.Set("event_bus_name", busName) + } + d.Set("name", ruleName) + + return []*schema.ResourceData{d}, nil +} diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index aab1f3533fc..006566636d2 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -86,6 +86,7 @@ func TestAccAWSCloudWatchEventRule_basic(t *testing.T) { testAccCheckCloudWatchEventRuleExists(resourceName, &rule), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(`rule/.+`)), resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckNoResourceAttr(resourceName, "event_bus_name"), resource.TestCheckResourceAttr(resourceName, "schedule_expression", "rate(1 hour)"), resource.TestCheckResourceAttr(resourceName, "role_arn", ""), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -398,6 +399,7 @@ func testAccAWSCloudWatchEventRuleConfig(name string) string { resource "aws_cloudwatch_event_rule" "test" { name = "%s" schedule_expression = "rate(1 hour)" + event_bus_name = "default" } `, name) } diff --git a/website/docs/r/cloudwatch_event_rule.html.markdown b/website/docs/r/cloudwatch_event_rule.html.markdown index ae6131be17d..4f2704543a0 100644 --- a/website/docs/r/cloudwatch_event_rule.html.markdown +++ b/website/docs/r/cloudwatch_event_rule.html.markdown @@ -64,6 +64,7 @@ The following arguments are supported: * `name_prefix` - (Optional) The rule's name. Conflicts with `name`. * `schedule_expression` - (Required, if `event_pattern` isn't specified) The scheduling expression. For example, `cron(0 20 * * ? *)` or `rate(5 minutes)`. +* `event_bus_name` - (Optional) The event bus to associate with this rule. If you omit this, the `default` event bus is used. * `event_pattern` - (Required, if `schedule_expression` isn't specified) Event pattern described a JSON object. See full documentation of [CloudWatch Events and Event Patterns](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CloudWatchEventsandEventPatterns.html) for details. @@ -82,7 +83,7 @@ In addition to all arguments above, the following attributes are exported: ## Import -Cloudwatch Event Rules can be imported using the `name`, e.g. +Cloudwatch Event Rules can be imported using the `event_bus_name/rule_name` (if you omit `event_bus_name`, the `default` event bus will be used), e.g. ``` $ terraform import aws_cloudwatch_event_rule.console capture-console-sign-in