From b756b54bb2db83b1f417e9abea23374a2bd668c8 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi Date: Sat, 30 Mar 2019 00:28:43 +0900 Subject: [PATCH] New Resource: aws_codepipeline_custom_action_type --- aws/provider.go | 1 + ...rce_aws_codepipeline_custom_action_type.go | 427 ++++++++++++++++++ ...ws_codepipeline_custom_action_type_test.go | 217 +++++++++ website/aws.erb | 3 + ...epipeline_custom_action_type.html.markdown | 87 ++++ 5 files changed, 735 insertions(+) create mode 100644 aws/resource_aws_codepipeline_custom_action_type.go create mode 100644 aws/resource_aws_codepipeline_custom_action_type_test.go create mode 100644 website/docs/r/codepipeline_custom_action_type.html.markdown diff --git a/aws/provider.go b/aws/provider.go index 99d3ff2c48a..eb6913d5973 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -373,6 +373,7 @@ func Provider() terraform.ResourceProvider { "aws_codebuild_project": resourceAwsCodeBuildProject(), "aws_codebuild_webhook": resourceAwsCodeBuildWebhook(), "aws_codepipeline": resourceAwsCodePipeline(), + "aws_codepipeline_custom_action_type": resourceAwsCodePipelineCustomActionType(), "aws_codepipeline_webhook": resourceAwsCodePipelineWebhook(), "aws_cur_report_definition": resourceAwsCurReportDefinition(), "aws_customer_gateway": resourceAwsCustomerGateway(), diff --git a/aws/resource_aws_codepipeline_custom_action_type.go b/aws/resource_aws_codepipeline_custom_action_type.go new file mode 100644 index 00000000000..b75357e5418 --- /dev/null +++ b/aws/resource_aws_codepipeline_custom_action_type.go @@ -0,0 +1,427 @@ +package aws + +import ( + "errors" + "fmt" + "log" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/codepipeline" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" +) + +func resourceAwsCodePipelineCustomActionType() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsCodePipelineCustomActionTypeCreate, + Read: resourceAwsCodePipelineCustomActionTypeRead, + Delete: resourceAwsCodePipelineCustomActionTypeDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "category": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + codepipeline.ActionCategorySource, + codepipeline.ActionCategoryBuild, + codepipeline.ActionCategoryDeploy, + codepipeline.ActionCategoryTest, + codepipeline.ActionCategoryInvoke, + codepipeline.ActionCategoryApproval, + }, false), + }, + "configuration_properties": { + Type: schema.TypeList, + MaxItems: 10, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Optional: true, + }, + "key": { + Type: schema.TypeBool, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "queryable": { + Type: schema.TypeBool, + Optional: true, + }, + "required": { + Type: schema.TypeBool, + Required: true, + }, + "secret": { + Type: schema.TypeBool, + Required: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + codepipeline.ActionConfigurationPropertyTypeString, + codepipeline.ActionConfigurationPropertyTypeNumber, + codepipeline.ActionConfigurationPropertyTypeBoolean, + }, false), + }, + }, + }, + }, + "input_artifact_details": { + Type: schema.TypeList, + ForceNew: true, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "maximum_count": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 5), + }, + "minimum_count": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 5), + }, + }, + }, + }, + "output_artifact_details": { + Type: schema.TypeList, + ForceNew: true, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "maximum_count": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 5), + }, + "minimum_count": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 5), + }, + }, + }, + }, + "provider_name": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 25), + }, + "settings": { + Type: schema.TypeList, + ForceNew: true, + Optional: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "entity_url_template": { + Type: schema.TypeString, + Optional: true, + }, + "execution_url_template": { + Type: schema.TypeString, + Optional: true, + }, + "revision_url_template": { + Type: schema.TypeString, + Optional: true, + }, + "third_party_configuration_url": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "version": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 9), + }, + "owner": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceAwsCodePipelineCustomActionTypeCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).codepipelineconn + + input := &codepipeline.CreateCustomActionTypeInput{ + Category: aws.String(d.Get("category").(string)), + InputArtifactDetails: expandAwsCodePipelineArtifactDetails(d.Get("input_artifact_details").([]interface{})[0].(map[string]interface{})), + OutputArtifactDetails: expandAwsCodePipelineArtifactDetails(d.Get("output_artifact_details").([]interface{})[0].(map[string]interface{})), + Provider: aws.String(d.Get("provider_name").(string)), + Version: aws.String(d.Get("version").(string)), + } + + confProps := d.Get("configuration_properties").([]interface{}) + if len(confProps) > 0 { + input.ConfigurationProperties = expandAwsCodePipelineActionConfigurationProperty(confProps) + } + + settings := d.Get("settings").([]interface{}) + if len(settings) > 0 { + input.Settings = expandAwsCodePipelineActionTypeSettings(settings[0].(map[string]interface{})) + } + + resp, err := conn.CreateCustomActionType(input) + if err != nil { + return fmt.Errorf("Error creating CodePipeline CustomActionType: %s", err) + } + + if resp.ActionType == nil || resp.ActionType.Id == nil || + resp.ActionType.Id.Owner == nil || resp.ActionType.Id.Category == nil || resp.ActionType.Id.Provider == nil || resp.ActionType.Id.Version == nil { + return errors.New("Error creating CodePipeline CustomActionType: invalid response from AWS") + } + d.SetId(fmt.Sprintf("%s:%s:%s:%s", *resp.ActionType.Id.Owner, *resp.ActionType.Id.Category, *resp.ActionType.Id.Provider, *resp.ActionType.Id.Version)) + return resourceAwsCodePipelineCustomActionTypeRead(d, meta) +} + +func resourceAwsCodePipelineCustomActionTypeRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).codepipelineconn + owner, category, provider, version, err := decodeAwsCodePipelineCustomActionTypeId(d.Id()) + if err != nil { + return fmt.Errorf("Error reading CodePipeline CustomActionType: %s", err) + } + + actionType, err := lookAwsCodePipelineCustomActionType(conn, d.Id()) + if err != nil { + return fmt.Errorf("Error reading CodePipeline CustomActionType: %s", err) + } + if actionType == nil { + log.Printf("[INFO] Codepipeline CustomActionType %q not found", d.Id()) + d.SetId("") + return nil + } + + d.Set("owner", owner) + d.Set("category", category) + d.Set("provider_name", provider) + d.Set("version", version) + + if err := d.Set("configuration_properties", flattenAwsCodePipelineActionConfigurationProperty(actionType.ActionConfigurationProperties)); err != nil { + return fmt.Errorf("error setting configuration_properties: %s", err) + } + + if err := d.Set("input_artifact_details", flattenAwsCodePipelineArtifactDetails(actionType.InputArtifactDetails)); err != nil { + return fmt.Errorf("error setting input_artifact_details: %s", err) + } + + if err := d.Set("output_artifact_details", flattenAwsCodePipelineArtifactDetails(actionType.OutputArtifactDetails)); err != nil { + return fmt.Errorf("error setting output_artifact_details: %s", err) + } + + if err := d.Set("settings", flattenAwsCodePipelineActionTypeSettings(actionType.Settings)); err != nil { + return fmt.Errorf("error setting settings: %s", err) + } + + return nil +} + +func resourceAwsCodePipelineCustomActionTypeDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).codepipelineconn + + _, category, provider, version, err := decodeAwsCodePipelineCustomActionTypeId(d.Id()) + if err != nil { + return fmt.Errorf("Error deleting CodePipeline CustomActionType: %s", err) + } + + input := &codepipeline.DeleteCustomActionTypeInput{ + Category: aws.String(category), + Provider: aws.String(provider), + Version: aws.String(version), + } + + _, err = conn.DeleteCustomActionType(input) + if err != nil { + if isAWSErr(err, codepipeline.ErrCodeActionTypeNotFoundException, "") { + return nil + } + return fmt.Errorf("error deleting CodePipeline CustomActionType (%s): %s", d.Id(), err) + } + + return nil +} + +func lookAwsCodePipelineCustomActionType(conn *codepipeline.CodePipeline, id string) (*codepipeline.ActionType, error) { + owner, category, provider, version, err := decodeAwsCodePipelineCustomActionTypeId(id) + if err != nil { + return nil, fmt.Errorf("Error reading CodePipeline CustomActionType: %s", err) + } + + var actionType *codepipeline.ActionType + + input := &codepipeline.ListActionTypesInput{ + ActionOwnerFilter: aws.String(owner), + } + for { + resp, err := conn.ListActionTypes(input) + if err != nil { + return nil, fmt.Errorf("Error reading CodePipeline CustomActionType: %s", err) + } + + for _, v := range resp.ActionTypes { + if atid := v.Id; atid != nil { + if atid.Category == nil || atid.Provider == nil || atid.Version == nil { + continue + } + if *atid.Category == category && *atid.Provider == provider && *atid.Version == version { + actionType = v + break + } + } + } + + if actionType != nil { + break + } + + if resp.NextToken == nil { + break + } else { + input.NextToken = resp.NextToken + } + } + + return actionType, nil +} + +func decodeAwsCodePipelineCustomActionTypeId(id string) (owner string, category string, provider string, version string, e error) { + ss := strings.Split(id, ":") + if len(ss) != 4 { + e = fmt.Errorf("invalid AwsCodePipelineCustomActionType ID: %s", id) + return + } + owner, category, provider, version = ss[0], ss[1], ss[2], ss[3] + return +} + +func expandAwsCodePipelineArtifactDetails(d map[string]interface{}) *codepipeline.ArtifactDetails { + return &codepipeline.ArtifactDetails{ + MaximumCount: aws.Int64(int64(d["maximum_count"].(int))), + MinimumCount: aws.Int64(int64(d["minimum_count"].(int))), + } +} + +func flattenAwsCodePipelineArtifactDetails(ad *codepipeline.ArtifactDetails) []map[string]interface{} { + m := make(map[string]interface{}) + + m["maximum_count"] = aws.Int64Value(ad.MaximumCount) + m["minimum_count"] = aws.Int64Value(ad.MinimumCount) + + return []map[string]interface{}{m} +} + +func expandAwsCodePipelineActionConfigurationProperty(d []interface{}) []*codepipeline.ActionConfigurationProperty { + if len(d) == 0 { + return nil + } + result := make([]*codepipeline.ActionConfigurationProperty, 0, len(d)) + + for _, v := range d { + m := v.(map[string]interface{}) + acp := &codepipeline.ActionConfigurationProperty{ + Key: aws.Bool(m["key"].(bool)), + Name: aws.String(m["name"].(string)), + Required: aws.Bool(m["required"].(bool)), + Secret: aws.Bool(m["secret"].(bool)), + } + if raw, ok := m["description"]; ok && raw.(string) != "" { + acp.Description = aws.String(raw.(string)) + } + if raw, ok := m["queryable"]; ok { + acp.Queryable = aws.Bool(raw.(bool)) + } + if raw, ok := m["type"]; ok && raw.(string) != "" { + acp.Type = aws.String(raw.(string)) + } + result = append(result, acp) + } + + return result +} + +func flattenAwsCodePipelineActionConfigurationProperty(acps []*codepipeline.ActionConfigurationProperty) []interface{} { + result := make([]interface{}, 0, len(acps)) + + for _, acp := range acps { + m := map[string]interface{}{} + m["description"] = aws.StringValue(acp.Description) + m["key"] = aws.BoolValue(acp.Key) + m["name"] = aws.StringValue(acp.Name) + m["queryable"] = aws.BoolValue(acp.Queryable) + m["required"] = aws.BoolValue(acp.Required) + m["secret"] = aws.BoolValue(acp.Secret) + m["type"] = aws.StringValue(acp.Type) + result = append(result, m) + } + return result +} + +func expandAwsCodePipelineActionTypeSettings(d map[string]interface{}) *codepipeline.ActionTypeSettings { + if len(d) == 0 { + return nil + } + result := &codepipeline.ActionTypeSettings{} + + if raw, ok := d["entity_url_template"]; ok && raw.(string) != "" { + result.EntityUrlTemplate = aws.String(raw.(string)) + } + if raw, ok := d["execution_url_template"]; ok && raw.(string) != "" { + result.ExecutionUrlTemplate = aws.String(raw.(string)) + } + if raw, ok := d["revision_url_template"]; ok && raw.(string) != "" { + result.RevisionUrlTemplate = aws.String(raw.(string)) + } + if raw, ok := d["third_party_configuration_url"]; ok && raw.(string) != "" { + result.ThirdPartyConfigurationUrl = aws.String(raw.(string)) + } + + return result +} + +func flattenAwsCodePipelineActionTypeSettings(settings *codepipeline.ActionTypeSettings) []map[string]interface{} { + m := make(map[string]interface{}) + + if settings.EntityUrlTemplate != nil { + m["entity_url_template"] = aws.StringValue(settings.EntityUrlTemplate) + } + if settings.ExecutionUrlTemplate != nil { + m["execution_url_template"] = aws.StringValue(settings.ExecutionUrlTemplate) + } + if settings.RevisionUrlTemplate != nil { + m["revision_url_template"] = aws.StringValue(settings.RevisionUrlTemplate) + } + if settings.ThirdPartyConfigurationUrl != nil { + m["third_party_configuration_url"] = aws.StringValue(settings.ThirdPartyConfigurationUrl) + } + + if len(m) == 0 { + return nil + } + return []map[string]interface{}{m} +} diff --git a/aws/resource_aws_codepipeline_custom_action_type_test.go b/aws/resource_aws_codepipeline_custom_action_type_test.go new file mode 100644 index 00000000000..5a135af865f --- /dev/null +++ b/aws/resource_aws_codepipeline_custom_action_type_test.go @@ -0,0 +1,217 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAwsCodePipelineCustomActionType_basic(t *testing.T) { + resourceName := "aws_codepipeline_custom_action_type.test" + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsCodePipelineCustomActionTypeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsCodePipelineCustomActionType_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsCodePipelineCustomActionTypeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "category", "Build"), + resource.TestCheckResourceAttr(resourceName, "input_artifact_details.#", "1"), + resource.TestCheckResourceAttr(resourceName, "input_artifact_details.0.maximum_count", "1"), + resource.TestCheckResourceAttr(resourceName, "input_artifact_details.0.minimum_count", "0"), + resource.TestCheckResourceAttr(resourceName, "output_artifact_details.#", "1"), + resource.TestCheckResourceAttr(resourceName, "output_artifact_details.0.maximum_count", "1"), + resource.TestCheckResourceAttr(resourceName, "input_artifact_details.0.minimum_count", "0"), + resource.TestCheckResourceAttr(resourceName, "provider_name", fmt.Sprintf("tf-%s", rName)), + resource.TestCheckResourceAttr(resourceName, "version", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsCodePipelineCustomActionType_settings(t *testing.T) { + resourceName := "aws_codepipeline_custom_action_type.test" + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsCodePipelineCustomActionTypeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsCodePipelineCustomActionType_settings(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsCodePipelineCustomActionTypeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "settings.#", "1"), + resource.TestCheckResourceAttr(resourceName, "settings.0.entity_url_template", "http://example.com"), + resource.TestCheckResourceAttr(resourceName, "settings.0.execution_url_template", "http://example.com"), + resource.TestCheckResourceAttr(resourceName, "settings.0.revision_url_template", "http://example.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsCodePipelineCustomActionType_configurationProperties(t *testing.T) { + resourceName := "aws_codepipeline_custom_action_type.test" + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsCodePipelineCustomActionTypeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsCodePipelineCustomActionType_configurationProperties(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsCodePipelineCustomActionTypeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.#", "1"), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.0.description", "tf-test"), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.0.key", "true"), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.0.name", fmt.Sprintf("tf-test-%s", rName)), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.0.queryable", "true"), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.0.required", "true"), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.0.secret", "false"), + resource.TestCheckResourceAttr(resourceName, "configuration_properties.0.type", "String"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckAwsCodePipelineCustomActionTypeExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No CodePipeline CustomActionType is set as ID") + } + + conn := testAccProvider.Meta().(*AWSClient).codepipelineconn + + actionType, err := lookAwsCodePipelineCustomActionType(conn, rs.Primary.ID) + if err != nil { + return err + } + if actionType == nil { + return fmt.Errorf("Not found CodePipeline CustomActionType: %s", rs.Primary.ID) + } + return nil + } +} + +func testAccCheckAwsCodePipelineCustomActionTypeDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).codepipelineconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_codepipeline_custom_action_type" { + continue + } + + actionType, err := lookAwsCodePipelineCustomActionType(conn, rs.Primary.ID) + if err != nil { + return fmt.Errorf("Error reading CodePipeline CustomActionType: %s", err) + } + if actionType != nil { + return fmt.Errorf("CodePipeline CustomActionType still exists: %s", rs.Primary.ID) + } + + return err + } + + return nil +} + +func testAccAwsCodePipelineCustomActionType_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_codepipeline_custom_action_type" "test" { + category = "Build" + input_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + output_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + provider_name = "tf-%s" + version = "1" +} +`, rName) +} + +func testAccAwsCodePipelineCustomActionType_settings(rName string) string { + return fmt.Sprintf(` +resource "aws_codepipeline_custom_action_type" "test" { + category = "Build" + input_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + output_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + provider_name = "tf-%s" + version = "1" + settings { + entity_url_template = "http://example.com" + execution_url_template = "http://example.com" + revision_url_template = "http://example.com" + } +} +`, rName) +} + +func testAccAwsCodePipelineCustomActionType_configurationProperties(rName string) string { + return fmt.Sprintf(` +resource "aws_codepipeline_custom_action_type" "test" { + category = "Build" + input_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + output_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + provider_name = "tf-%s" + version = "1" + configuration_properties { + description = "tf-test" + key = true + name = "tf-test-%s" + queryable = true + required = true + secret = false + type = "String" + } +} +`, rName, rName) +} diff --git a/website/aws.erb b/website/aws.erb index 85027570777..2d489216e14 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -781,6 +781,9 @@ aws_codepipeline + > + aws_codepipeline_custom_action_type + > aws_codepipeline_webhook diff --git a/website/docs/r/codepipeline_custom_action_type.html.markdown b/website/docs/r/codepipeline_custom_action_type.html.markdown new file mode 100644 index 00000000000..9e0454c5f70 --- /dev/null +++ b/website/docs/r/codepipeline_custom_action_type.html.markdown @@ -0,0 +1,87 @@ +--- +layout: "aws" +page_title: "AWS: aws_codepipeline_custom_action_type" +sidebar_current: "docs-aws-resource-codepipeline-webhook" +description: |- + Provides a CodePipeline CustomActionType. +--- + +# aws_codepipeline_custom_action_type + +Provides a CodeDeploy CustomActionType + +## Example Usage + +```hcl +resource "aws_codepipeline_custom_action_type" "example" { + category = "Build" + input_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + output_artifact_details { + maximum_count = 1 + minimum_count = 0 + } + provider_name = "example" + version = "1" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `category` - (Required) The category of the custom action. Valid values: `Source`, `Build`, `Deploy`, `Test`, `Invoke`, `Approval` +* `configuration_properties` - (Optional) The configuration properties for the custom action. Max 10 items. + +The `configuration_properties` object supports the following: + +* `description` - (Optional) The description of the action configuration property. +* `key` - (Required) Whether the configuration property is a key. +* `name` - (Required) The name of the action configuration property. +* `queryable` - (Optional) Indicates that the property will be used in conjunction with PollForJobs. +* `required` - (Required) Whether the configuration property is a required value. +* `secret`- (Required) Whether the configuration property is secret. +* `type`- (Optional) The type of the configuration property. Valid values: `String`, `Number`, `Boolean` + +* `input_artifact_details` - (Required) The details of the input artifact for the action. + +The `input_artifact_details` object supports the following: + +* `maximum_count` - (Required) The maximum number of artifacts allowed for the action type. Min: 0, Max: 5 +* `minimum_count` - (Required) The minimum number of artifacts allowed for the action type. Min: 0, Max: 5 + +* `output_artifact_details` - (Required) The details of the output artifact of the action. + +The `output_artifact_details` object supports the following: + +* `maximum_count` - (Required) The maximum number of artifacts allowed for the action type. Min: 0, Max: 5 +* `minimum_count` - (Required) The minimum number of artifacts allowed for the action type. Min: 0, Max: 5 + +* `provider_name` - (Required) The provider of the service used in the custom action +* `settings` - (Optional) The settings for an action type. + +The `settings` object supports the following: + +* `entity_url_template` - (Optional) The URL returned to the AWS CodePipeline console that provides a deep link to the resources of the external system. +* `execution_url_template` - (Optional) The URL returned to the AWS CodePipeline console that contains a link to the top-level landing page for the external system. +* `revision_url_template` - (Optional) The URL returned to the AWS CodePipeline console that contains a link to the page where customers can update or change the configuration of the external action. +* `third_party_configuration_url` - (Optional) The URL of a sign-up page where users can sign up for an external service and perform initial configuration of the action provided by that service. + +* `version` - (Required) The version identifier of the custom action. + +## Attribute Reference + +The following arguments are exported: + +* `id` - Composed of owner, category, provider and version. For example, `Custom:Build:terraform:1` +* `owner` - The creator of the action being called. + +## Import + +CodeDeploy CustomActionType can be imported using the `id`, e.g. + +``` +$ terraform import aws_codepipeline_custom_action_type.example Custom:Build:terraform:1 +```