Skip to content

Commit

Permalink
Merge pull request #14910 from DrFaust92/r/workflow_tags
Browse files Browse the repository at this point in the history
r/glue_workflow - add tagging support + arn + max concurrent runs
  • Loading branch information
breathingdust authored Sep 23, 2020
2 parents f6f9648 + a21cc55 commit 867ae3b
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 32 deletions.
96 changes: 69 additions & 27 deletions aws/resource_aws_glue_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/glue"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"log"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsGlueWorkflow() *schema.Resource {
Expand All @@ -20,6 +23,10 @@ func resourceAwsGlueWorkflow() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"default_run_properties": {
Type: schema.TypeMap,
Optional: true,
Expand All @@ -29,12 +36,17 @@ func resourceAwsGlueWorkflow() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"max_concurrent_runs": {
Type: schema.TypeInt,
Optional: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.NoZeroValues,
ValidateFunc: validation.StringLenBetween(1, 255),
},
"tags": tagsSchema(),
},
}
}
Expand All @@ -45,24 +57,25 @@ func resourceAwsGlueWorkflowCreate(d *schema.ResourceData, meta interface{}) err

input := &glue.CreateWorkflowInput{
Name: aws.String(name),
Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().GlueTags(),
}

if kv, ok := d.GetOk("default_run_properties"); ok {
defaultRunPropertiesMap := make(map[string]string)
for k, v := range kv.(map[string]interface{}) {
defaultRunPropertiesMap[k] = v.(string)
}
input.DefaultRunProperties = aws.StringMap(defaultRunPropertiesMap)
input.DefaultRunProperties = stringMapToPointers(kv.(map[string]interface{}))
}

if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
}

if v, ok := d.GetOk("max_concurrent_runs"); ok {
input.MaxConcurrentRuns = aws.Int64(int64(v.(int)))
}

log.Printf("[DEBUG] Creating Glue Workflow: %s", input)
_, err := conn.CreateWorkflow(input)
if err != nil {
return fmt.Errorf("error creating Glue Trigger (%s): %s", name, err)
return fmt.Errorf("error creating Glue Trigger (%s): %w", name, err)
}
d.SetId(name)

Expand All @@ -71,20 +84,21 @@ func resourceAwsGlueWorkflowCreate(d *schema.ResourceData, meta interface{}) err

func resourceAwsGlueWorkflowRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).glueconn
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

input := &glue.GetWorkflowInput{
Name: aws.String(d.Id()),
}

log.Printf("[DEBUG] Reading Glue Workflow: %s", input)
log.Printf("[DEBUG] Reading Glue Workflow: %#v", input)
output, err := conn.GetWorkflow(input)
if err != nil {
if isAWSErr(err, glue.ErrCodeEntityNotFoundException, "") {
log.Printf("[WARN] Glue Workflow (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("error reading Glue Workflow (%s): %s", d.Id(), err)
return fmt.Errorf("error reading Glue Workflow (%s): %w", d.Id(), err)
}

workflow := output.Workflow
Expand All @@ -94,38 +108,66 @@ func resourceAwsGlueWorkflowRead(d *schema.ResourceData, meta interface{}) error
return nil
}

workFlowArn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Service: "glue",
Region: meta.(*AWSClient).region,
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("workflow/%s", d.Id()),
}.String()
d.Set("arn", workFlowArn)

if err := d.Set("default_run_properties", aws.StringValueMap(workflow.DefaultRunProperties)); err != nil {
return fmt.Errorf("error setting default_run_properties: %s", err)
return fmt.Errorf("error setting default_run_properties: %w", err)
}
d.Set("description", workflow.Description)
d.Set("name", workflow.Name)

tags, err := keyvaluetags.GlueListTags(conn, workFlowArn)

if err != nil {
return fmt.Errorf("error listing tags for Glue Workflow (%s): %w", workFlowArn, err)
}

if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %w", err)
}

return nil
}

func resourceAwsGlueWorkflowUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).glueconn

input := &glue.UpdateWorkflowInput{
Name: aws.String(d.Get("name").(string)),
}
if d.HasChanges("default_run_properties", "description", "max_concurrent_runs") {
input := &glue.UpdateWorkflowInput{
Name: aws.String(d.Get("name").(string)),
}

if kv, ok := d.GetOk("default_run_properties"); ok {
defaultRunPropertiesMap := make(map[string]string)
for k, v := range kv.(map[string]interface{}) {
defaultRunPropertiesMap[k] = v.(string)
if kv, ok := d.GetOk("default_run_properties"); ok {
input.DefaultRunProperties = stringMapToPointers(kv.(map[string]interface{}))
}
input.DefaultRunProperties = aws.StringMap(defaultRunPropertiesMap)
}

if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
}

if v, ok := d.GetOk("max_concurrent_runs"); ok {
input.MaxConcurrentRuns = aws.Int64(int64(v.(int)))
}

log.Printf("[DEBUG] Updating Glue Workflow: %#v", input)
_, err := conn.UpdateWorkflow(input)
if err != nil {
return fmt.Errorf("error updating Glue Workflow (%s): %w", d.Id(), err)
}
}

log.Printf("[DEBUG] Updating Glue Workflow: %s", input)
_, err := conn.UpdateWorkflow(input)
if err != nil {
return fmt.Errorf("error updating Glue Workflow (%s): %s", d.Id(), err)
if d.HasChange("tags") {
o, n := d.GetChange("tags")
if err := keyvaluetags.GlueUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating tags: %s", err)
}
}

return resourceAwsGlueWorkflowRead(d, meta)
Expand All @@ -137,7 +179,7 @@ func resourceAwsGlueWorkflowDelete(d *schema.ResourceData, meta interface{}) err
log.Printf("[DEBUG] Deleting Glue Workflow: %s", d.Id())
err := deleteWorkflow(conn, d.Id())
if err != nil {
return fmt.Errorf("error deleting Glue Workflow (%s): %s", d.Id(), err)
return fmt.Errorf("error deleting Glue Workflow (%s): %w", d.Id(), err)
}

return nil
Expand Down
150 changes: 147 additions & 3 deletions aws/resource_aws_glue_workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func testSweepGlueWorkflow(region string) error {
func TestAccAWSGlueWorkflow_basic(t *testing.T) {
var workflow glue.Workflow

rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_glue_workflow.test"

resource.ParallelTest(t, resource.TestCase{
Expand All @@ -59,7 +59,9 @@ func TestAccAWSGlueWorkflow_basic(t *testing.T) {
Config: testAccAWSGlueWorkflowConfig_Required(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
testAccCheckResourceAttrRegionalARN(resourceName, "arn", "glue", fmt.Sprintf("workflow/%s", rName)),
resource.TestCheckResourceAttr(resourceName, "name", rName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
},
{
Expand All @@ -71,10 +73,51 @@ func TestAccAWSGlueWorkflow_basic(t *testing.T) {
})
}

func TestAccAWSGlueWorkflow_maxConcurrentRuns(t *testing.T) {
var workflow glue.Workflow

rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_glue_workflow.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSGlueWorkflow(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSGlueWorkflowDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSGlueWorkflowConfigMaxConcurrentRuns(rName, 1),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
resource.TestCheckResourceAttr(resourceName, "max_concurrent_runs", "1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAWSGlueWorkflowConfigMaxConcurrentRuns(rName, 2),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
resource.TestCheckResourceAttr(resourceName, "max_concurrent_runs", "2"),
),
},
{
Config: testAccAWSGlueWorkflowConfigMaxConcurrentRuns(rName, 1),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
resource.TestCheckResourceAttr(resourceName, "max_concurrent_runs", "1"),
),
},
},
})
}

func TestAccAWSGlueWorkflow_DefaultRunProperties(t *testing.T) {
var workflow glue.Workflow

rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_glue_workflow.test"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -103,7 +146,7 @@ func TestAccAWSGlueWorkflow_DefaultRunProperties(t *testing.T) {
func TestAccAWSGlueWorkflow_Description(t *testing.T) {
var workflow glue.Workflow

rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_glue_workflow.test"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -134,6 +177,73 @@ func TestAccAWSGlueWorkflow_Description(t *testing.T) {
})
}

func TestAccAWSGlueWorkflow_Tags(t *testing.T) {
var workflow glue.Workflow
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_glue_workflow.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSGlueWorkflow(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSGlueWorkflowDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSGlueWorkflowConfigTags1(rName, "key1", "value1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAWSGlueWorkflowConfigTags2(rName, "key1", "value1updated", "key2", "value2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
{
Config: testAccAWSGlueWorkflowConfigTags1(rName, "key2", "value2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
},
})
}

func TestAccAWSGlueWorkflow_disappears(t *testing.T) {
var workflow glue.Workflow

rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_glue_workflow.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSGlueWorkflow(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSGlueWorkflowDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSGlueWorkflowConfig_Required(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSGlueWorkflowExists(resourceName, &workflow),
testAccCheckResourceDisappears(testAccProvider, resourceAwsGlueWorkflow(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccPreCheckAWSGlueWorkflow(t *testing.T) {
conn := testAccProvider.Meta().(*AWSClient).glueconn

Expand Down Expand Up @@ -241,3 +351,37 @@ resource "aws_glue_workflow" "test" {
}
`, rName)
}

func testAccAWSGlueWorkflowConfigMaxConcurrentRuns(rName string, runs int) string {
return fmt.Sprintf(`
resource "aws_glue_workflow" "test" {
name = %[1]q
max_concurrent_runs = %[2]d
}
`, rName, runs)
}

func testAccAWSGlueWorkflowConfigTags1(rName, tagKey1, tagValue1 string) string {
return fmt.Sprintf(`
resource "aws_glue_workflow" "test" {
name = %[1]q
tags = {
%[2]q = %[3]q
}
}
`, rName, tagKey1, tagValue1)
}

func testAccAWSGlueWorkflowConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
return fmt.Sprintf(`
resource "aws_glue_workflow" "test" {
name = %[1]q
tags = {
%[2]q = %[3]q
%[4]q = %[5]q
}
}
`, rName, tagKey1, tagValue1, tagKey2, tagValue2)
}
1 change: 1 addition & 0 deletions website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ for more information about connecting to alternate AWS endpoints or AWS compatib
- [`aws_glue_job` resource](/docs/providers/aws/r/glue_job.html)
- [`aws_glue_trigger` resource](/docs/providers/aws/r/glue_trigger.html)
- [`aws_glue_user_defined_function` resource](/docs/providers/aws/r/glue_user_defined_function.html)
- [`aws_glue_workflow` resource](/docs/providers/aws/r/glue_workflow.html)
- [`aws_guardduty_detector` resource](/docs/providers/aws/r/guardduty_detector.html)
- [`aws_guardduty_ipset` resource](/docs/providers/aws/r/guardduty_ipset.html)
- [`aws_guardduty_threatintelset` resource](/docs/providers/aws/r/guardduty_threatintelset.html)
Expand Down
Loading

0 comments on commit 867ae3b

Please sign in to comment.