diff --git a/aws/data_source_aws_lex_bot_alias.go b/aws/data_source_aws_lex_bot_alias.go new file mode 100644 index 000000000000..905dcbb92f89 --- /dev/null +++ b/aws/data_source_aws_lex_bot_alias.go @@ -0,0 +1,97 @@ +package aws + +import ( + "fmt" + "regexp" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/lexmodelbuildingservice" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceAwsLexBotAlias() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsLexBotAliasRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "bot_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(2, 50), + validation.StringMatch(regexp.MustCompile(`^([A-Za-z]_?)+$`), ""), + ), + }, + "bot_version": { + Type: schema.TypeString, + Computed: true, + }, + "checksum": { + Type: schema.TypeString, + Computed: true, + }, + "created_date": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "last_updated_date": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 100), + validation.StringMatch(regexp.MustCompile(`^([A-Za-z]_?)+$`), ""), + ), + }, + }, + } +} + +func dataSourceAwsLexBotAliasRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lexmodelconn + + botName := d.Get("bot_name").(string) + botAliasName := d.Get("name").(string) + d.SetId(fmt.Sprintf("%s:%s", botName, botAliasName)) + + resp, err := conn.GetBotAlias(&lexmodelbuildingservice.GetBotAliasInput{ + BotName: aws.String(botName), + Name: aws.String(botAliasName), + }) + if err != nil { + return fmt.Errorf("error getting bot alias '%s': %w", d.Id(), err) + } + + arn := arn.ARN{ + Partition: meta.(*AWSClient).partition, + Region: meta.(*AWSClient).region, + Service: "lex", + AccountID: meta.(*AWSClient).accountid, + Resource: fmt.Sprintf("bot:%s", d.Id()), + } + d.Set("arn", arn.String()) + + d.Set("bot_name", resp.BotName) + d.Set("bot_version", resp.BotVersion) + d.Set("checksum", resp.Checksum) + d.Set("created_date", resp.CreatedDate.Format(time.RFC3339)) + d.Set("description", resp.Description) + d.Set("last_updated_date", resp.LastUpdatedDate.Format(time.RFC3339)) + d.Set("name", resp.Name) + + return nil +} diff --git a/aws/data_source_aws_lex_bot_alias_test.go b/aws/data_source_aws_lex_bot_alias_test.go new file mode 100644 index 000000000000..0a6e31efddc3 --- /dev/null +++ b/aws/data_source_aws_lex_bot_alias_test.go @@ -0,0 +1,48 @@ +package aws + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceAwsLexBotAlias_basic(t *testing.T) { + rName := acctest.RandStringFromCharSet(8, acctest.CharSetAlpha) + dataSourceName := "data.aws_lex_bot_alias.test" + resourceName := "aws_lex_bot_alias.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(rName), + testAccAwsLexBotConfig_createVersion(rName), + testAccAwsLexBotAliasConfig_basic(rName), + testAccDataSourceAwsLexBotAliasConfig_basic(), + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "bot_name", resourceName, "bot_name"), + resource.TestCheckResourceAttrPair(dataSourceName, "bot_version", resourceName, "bot_version"), + resource.TestCheckResourceAttrPair(dataSourceName, "checksum", resourceName, "checksum"), + resource.TestCheckResourceAttrPair(dataSourceName, "created_date", resourceName, "created_date"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "last_updated_date", resourceName, "last_updated_date"), + resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsLexBotAliasConfig_basic() string { + return ` +data "aws_lex_bot_alias" "test" { + name = aws_lex_bot_alias.test.name + bot_name = aws_lex_bot.test.name +} +` +} diff --git a/aws/internal/service/lex/waiter/status.go b/aws/internal/service/lex/waiter/status.go index 448c14d9e5bd..3fa9d3d31d26 100644 --- a/aws/internal/service/lex/waiter/status.go +++ b/aws/internal/service/lex/waiter/status.go @@ -72,3 +72,24 @@ func LexBotStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id stri return output, LexModelBuildingServiceStatusCreated, nil } } + +func LexBotAliasStatus(conn *lexmodelbuildingservice.LexModelBuildingService, botAliasName, botName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := conn.GetBotAlias(&lexmodelbuildingservice.GetBotAliasInput{ + BotName: aws.String(botName), + Name: aws.String(botAliasName), + }) + if tfawserr.ErrCodeEquals(err, lexmodelbuildingservice.ErrCodeNotFoundException) { + return nil, LexModelBuildingServiceStatusNotFound, nil + } + if err != nil { + return nil, LexModelBuildingServiceStatusUnknown, err + } + + if output == nil { + return nil, LexModelBuildingServiceStatusNotFound, nil + } + + return output, LexModelBuildingServiceStatusCreated, nil + } +} diff --git a/aws/internal/service/lex/waiter/waiter.go b/aws/internal/service/lex/waiter/waiter.go index 28932e9a9ce9..1dedcd644f76 100644 --- a/aws/internal/service/lex/waiter/waiter.go +++ b/aws/internal/service/lex/waiter/waiter.go @@ -29,6 +29,22 @@ func LexBotDeleted(conn *lexmodelbuildingservice.LexModelBuildingService, botId return nil, err } +func LexBotAliasDeleted(conn *lexmodelbuildingservice.LexModelBuildingService, botAliasName, botName string) (*lexmodelbuildingservice.GetBotAliasOutput, error) { + stateChangeConf := &resource.StateChangeConf{ + Pending: []string{LexModelBuildingServiceStatusCreated}, + Target: []string{}, // An empty slice indicates that the resource is gone + Refresh: LexBotAliasStatus(conn, botAliasName, botName), + Timeout: LexBotDeleteTimeout, + } + outputRaw, err := stateChangeConf.WaitForState() + + if v, ok := outputRaw.(*lexmodelbuildingservice.GetBotAliasOutput); ok { + return v, err + } + + return nil, err +} + func LexIntentDeleted(conn *lexmodelbuildingservice.LexModelBuildingService, intentId string) (*lexmodelbuildingservice.GetIntentVersionsOutput, error) { stateChangeConf := &resource.StateChangeConf{ Pending: []string{LexModelBuildingServiceStatusCreated}, diff --git a/aws/provider.go b/aws/provider.go index fa2ca76cef64..b712fd6ef624 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -283,6 +283,7 @@ func Provider() *schema.Provider { "aws_launch_configuration": dataSourceAwsLaunchConfiguration(), "aws_launch_template": dataSourceAwsLaunchTemplate(), "aws_lex_bot": dataSourceAwsLexBot(), + "aws_lex_bot_alias": dataSourceAwsLexBotAlias(), "aws_lex_intent": dataSourceAwsLexIntent(), "aws_lex_slot_type": dataSourceAwsLexSlotType(), "aws_mq_broker": dataSourceAwsMqBroker(), @@ -717,6 +718,7 @@ func Provider() *schema.Provider { "aws_launch_configuration": resourceAwsLaunchConfiguration(), "aws_launch_template": resourceAwsLaunchTemplate(), "aws_lex_bot": resourceAwsLexBot(), + "aws_lex_bot_alias": resourceAwsLexBotAlias(), "aws_lex_intent": resourceAwsLexIntent(), "aws_lex_slot_type": resourceAwsLexSlotType(), "aws_licensemanager_association": resourceAwsLicenseManagerAssociation(), diff --git a/aws/resource_aws_lex_bot_alias.go b/aws/resource_aws_lex_bot_alias.go new file mode 100644 index 000000000000..6146ded96a75 --- /dev/null +++ b/aws/resource_aws_lex_bot_alias.go @@ -0,0 +1,361 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/lexmodelbuildingservice" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lex/waiter" +) + +const ( + LexBotAliasCreateTimeout = 1 * time.Minute + LexBotAliasUpdateTimeout = 1 * time.Minute + LexBotAliasDeleteTimeout = 5 * time.Minute +) + +func resourceAwsLexBotAlias() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsLexBotAliasCreate, + Read: resourceAwsLexBotAliasRead, + Update: resourceAwsLexBotAliasUpdate, + Delete: resourceAwsLexBotAliasDelete, + Importer: &schema.ResourceImporter{ + State: resourceAwsLexBotAliasImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(LexBotAliasCreateTimeout), + Update: schema.DefaultTimeout(LexBotAliasUpdateTimeout), + Delete: schema.DefaultTimeout(LexBotAliasDeleteTimeout), + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "bot_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(2, 50), + validation.StringMatch(regexp.MustCompile(`^([A-Za-z]_?)+$`), ""), + ), + }, + "bot_version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 64), + validation.StringMatch(regexp.MustCompile(`\$LATEST|[0-9]+`), ""), + ), + }, + "checksum": { + Type: schema.TypeString, + Computed: true, + }, + "conversation_logs": { + Type: schema.TypeList, + Optional: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "iam_role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(20, 2048), + validateArn, + ), + }, + // Currently the API docs do not list a min and max for this list. + // https://docs.aws.amazon.com/lex/latest/dg/API_PutBotAlias.html#lex-PutBotAlias-request-conversationLogs + "log_settings": { + Type: schema.TypeList, + Optional: true, + Elem: lexLogSettings, + }, + }, + }, + }, + "created_date": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Default: "", + ValidateFunc: validation.StringLenBetween(0, 200), + }, + "last_updated_date": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 100), + validation.StringMatch(regexp.MustCompile(`^([A-Za-z]_?)+$`), ""), + ), + }, + }, + } +} + +func resourceAwsLexBotAliasCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lexmodelconn + + botName := d.Get("bot_name").(string) + botAliasName := d.Get("name").(string) + id := fmt.Sprintf("%s:%s", botName, botAliasName) + + input := &lexmodelbuildingservice.PutBotAliasInput{ + BotName: aws.String(botName), + BotVersion: aws.String(d.Get("bot_version").(string)), + Description: aws.String(d.Get("description").(string)), + Name: aws.String(botAliasName), + } + + if v, ok := d.GetOk("conversation_logs"); ok { + input.ConversationLogs = expandLexConversationLogs(v) + } + + err := resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + output, err := conn.PutBotAlias(input) + + if tfawserr.ErrCodeEquals(err, lexmodelbuildingservice.ErrCodeConflictException) { + input.Checksum = output.Checksum + return resource.RetryableError(fmt.Errorf("%q bot alias still creating, another operation is pending: %w", id, err)) + } + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + if err != nil { + return fmt.Errorf("error creating bot alias '%s': %w", id, err) + } + + d.SetId(id) + + return resourceAwsLexBotAliasRead(d, meta) +} + +func resourceAwsLexBotAliasRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lexmodelconn + + resp, err := conn.GetBotAlias(&lexmodelbuildingservice.GetBotAliasInput{ + BotName: aws.String(d.Get("bot_name").(string)), + Name: aws.String(d.Get("name").(string)), + }) + if isAWSErr(err, lexmodelbuildingservice.ErrCodeNotFoundException, "") { + log.Printf("[WARN] Bot alias (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("error getting bot alias '%s': %w", d.Id(), err) + } + + arn := arn.ARN{ + Partition: meta.(*AWSClient).partition, + Region: meta.(*AWSClient).region, + Service: "lex", + AccountID: meta.(*AWSClient).accountid, + Resource: fmt.Sprintf("bot:%s", d.Id()), + } + d.Set("arn", arn.String()) + + d.Set("bot_name", resp.BotName) + d.Set("bot_version", resp.BotVersion) + d.Set("checksum", resp.Checksum) + d.Set("created_date", resp.CreatedDate.Format(time.RFC3339)) + d.Set("description", resp.Description) + d.Set("last_updated_date", resp.LastUpdatedDate.Format(time.RFC3339)) + d.Set("name", resp.Name) + + if resp.ConversationLogs != nil { + d.Set("conversation_logs", flattenLexConversationLogs(resp.ConversationLogs)) + } + + return nil +} + +func resourceAwsLexBotAliasUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lexmodelconn + + input := &lexmodelbuildingservice.PutBotAliasInput{ + BotName: aws.String(d.Get("bot_name").(string)), + BotVersion: aws.String(d.Get("bot_version").(string)), + Checksum: aws.String(d.Get("checksum").(string)), + Name: aws.String(d.Get("name").(string)), + } + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("conversation_logs"); ok { + input.ConversationLogs = expandLexConversationLogs(v) + } + + err := resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + _, err := conn.PutBotAlias(input) + + if isAWSErr(err, lexmodelbuildingservice.ErrCodeConflictException, "") { + return resource.RetryableError(fmt.Errorf("'%q': bot alias still updating", d.Id())) + } + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + if err != nil { + return fmt.Errorf("error updating bot alias '%s': %w", d.Id(), err) + } + + return resourceAwsLexBotAliasRead(d, meta) +} + +func resourceAwsLexBotAliasDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lexmodelconn + + botName := d.Get("bot_name").(string) + botAliasName := d.Get("name").(string) + + err := resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + _, err := conn.DeleteBotAlias(&lexmodelbuildingservice.DeleteBotAliasInput{ + BotName: aws.String(botName), + Name: aws.String(botAliasName), + }) + + if isAWSErr(err, lexmodelbuildingservice.ErrCodeConflictException, "") { + return resource.RetryableError(fmt.Errorf("'%q': bot alias still deleting", d.Id())) + } + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + if err != nil { + return fmt.Errorf("error deleting bot alias '%s': %w", d.Id(), err) + } + + _, err = waiter.LexBotAliasDeleted(conn, botAliasName, botName) + + return err +} + +func resourceAwsLexBotAliasImport(d *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) { + parts := strings.Split(d.Id(), ":") + if len(parts) != 2 { + return nil, fmt.Errorf("invalid Lex Bot Alias resource id '%s', expected BOT_NAME:BOT_ALIAS_NAME", d.Id()) + } + + d.Set("bot_name", parts[0]) + d.Set("name", parts[1]) + + return []*schema.ResourceData{d}, nil +} + +var lexLogSettings = &schema.Resource{ + Schema: map[string]*schema.Schema{ + "destination": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(lexmodelbuildingservice.Destination_Values(), false), + }, + "kms_key_arn": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.All( + validation.StringLenBetween(20, 2048), + validateArn, + ), + }, + "log_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(lexmodelbuildingservice.LogType_Values(), false), + }, + "resource_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 2048), + validateArn, + ), + }, + }, +} + +func flattenLexConversationLogs(response *lexmodelbuildingservice.ConversationLogsResponse) (flattened []map[string]interface{}) { + return []map[string]interface{}{ + { + "iam_role_arn": aws.StringValue(response.IamRoleArn), + "log_settings": flattenLexLogSettings(response.LogSettings), + }, + } +} + +func expandLexConversationLogs(rawObject interface{}) *lexmodelbuildingservice.ConversationLogsRequest { + request := rawObject.([]interface{})[0].(map[string]interface{}) + return &lexmodelbuildingservice.ConversationLogsRequest{ + IamRoleArn: aws.String(request["iam_role_arn"].(string)), + LogSettings: expandLexLogSettings(request["log_settings"].([]interface{})), + } +} + +func flattenLexLogSettings(responses []*lexmodelbuildingservice.LogSettingsResponse) (flattened []map[string]interface{}) { + for _, response := range responses { + flattened = append(flattened, map[string]interface{}{ + "destination": response.Destination, + "kms_key_arn": response.KmsKeyArn, + "log_type": response.LogType, + "resource_arn": response.ResourceArn, + }) + } + return +} + +func expandLexLogSettings(rawValues []interface{}) []*lexmodelbuildingservice.LogSettingsRequest { + requests := make([]*lexmodelbuildingservice.LogSettingsRequest, 0, len(rawValues)) + + for _, rawValue := range rawValues { + value, ok := rawValue.(map[string]interface{}) + if !ok { + continue + } + request := &lexmodelbuildingservice.LogSettingsRequest{ + Destination: aws.String(value["destination"].(string)), + LogType: aws.String(value["log_type"].(string)), + ResourceArn: aws.String(value["resource_arn"].(string)), + } + + if v, ok := value["kms_key_arn"]; ok && v != "" { + request.KmsKeyArn = aws.String(value["kms_key_arn"].(string)) + } + + requests = append(requests, request) + } + + return requests +} diff --git a/aws/resource_aws_lex_bot_alias_test.go b/aws/resource_aws_lex_bot_alias_test.go new file mode 100644 index 000000000000..6e2aa95cfb6e --- /dev/null +++ b/aws/resource_aws_lex_bot_alias_test.go @@ -0,0 +1,446 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/lexmodelbuildingservice" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccAwsLexBotAlias_basic(t *testing.T) { + var v lexmodelbuildingservice.GetBotAliasOutput + rName := "aws_lex_bot_alias.test" + testBotAliasID := "test_bot_alias" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsLexBotAliasDestroy(testBotAliasID, testBotAliasID), + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_basic(testBotAliasID), + testAccAwsLexBotAliasConfig_basic(testBotAliasID), + ), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + + resource.TestCheckResourceAttrSet(rName, "arn"), + resource.TestCheckResourceAttrSet(rName, "checksum"), + testAccCheckResourceAttrRfc3339(rName, "created_date"), + resource.TestCheckResourceAttr(rName, "description", "Testing lex bot alias create."), + testAccCheckResourceAttrRfc3339(rName, "last_updated_date"), + resource.TestCheckResourceAttr(rName, "bot_name", testBotAliasID), + resource.TestCheckResourceAttr(rName, "bot_version", "$LATEST"), + resource.TestCheckResourceAttr(rName, "name", testBotAliasID), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsLexBotAlias_botVersion(t *testing.T) { + var v lexmodelbuildingservice.GetBotAliasOutput + rName := "aws_lex_bot_alias.test" + testBotAliasID := "test_bot_alias" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsLexBotAliasDestroy(testBotAliasID, testBotAliasID), + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_basic(testBotAliasID), + testAccAwsLexBotAliasConfig_basic(testBotAliasID), + ), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_createVersion(testBotAliasID), + testAccAwsLexBotAliasConfig_botVersionUpdate(testBotAliasID), + ), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + resource.TestCheckResourceAttr(rName, "bot_version", "1"), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsLexBotAlias_conversationLogsText(t *testing.T) { + var v lexmodelbuildingservice.GetBotAliasOutput + rName := "aws_lex_bot_alias.test" + testBotAliasID := "test_bot_alias" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsLexBotAliasDestroy(testBotAliasID, testBotAliasID), + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAwsLexBotAliasConfig_conversationLogsTextSetup(testBotAliasID), + ), + }, + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_basic(testBotAliasID), + testAccAwsLexBotAliasConfig_conversationLogsTextSetup(testBotAliasID), + testAccAwsLexBotAliasConfig_conversationLogsText(testBotAliasID), + ), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsLexBotAlias_conversationLogsAudio(t *testing.T) { + var v lexmodelbuildingservice.GetBotAliasOutput + rName := "aws_lex_bot_alias.test" + testBotAliasID := acctest.RandStringFromCharSet(8, acctest.CharSetAlpha) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsLexBotAliasDestroy(testBotAliasID, testBotAliasID), + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAwsLexBotAliasConfig_conversationLogsAudioSetup(testBotAliasID), + ), + }, + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_basic(testBotAliasID), + testAccAwsLexBotAliasConfig_conversationLogsAudioSetup(testBotAliasID), + testAccAwsLexBotAliasConfig_conversationLogsAudio(testBotAliasID), + ), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsLexBotAlias_description(t *testing.T) { + var v lexmodelbuildingservice.GetBotAliasOutput + rName := "aws_lex_bot_alias.test" + testBotAliasID := "test_bot_alias" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsLexBotAliasDestroy(testBotAliasID, testBotAliasID), + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_basic(testBotAliasID), + testAccAwsLexBotAliasConfig_basic(testBotAliasID), + ), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_basic(testBotAliasID), + testAccAwsLexBotAliasConfig_descriptionUpdate(testBotAliasID), + ), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + resource.TestCheckResourceAttr(rName, "description", "Testing lex bot alias update."), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsLexBotAlias_disappears(t *testing.T) { + var v lexmodelbuildingservice.GetBotAliasOutput + rName := "aws_lex_bot_alias.test" + testBotAliasID := "test_bot_alias" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsLexBotDestroy, + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAwsLexBotConfig_intent(testBotAliasID), + testAccAwsLexBotConfig_basic(testBotAliasID), + testAccAwsLexBotAliasConfig_basic(testBotAliasID), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLexBotAliasExists(rName, &v), + testAccCheckResourceDisappears(testAccProvider, resourceAwsLexBotAlias(), rName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckAwsLexBotAliasExists(rName string, output *lexmodelbuildingservice.GetBotAliasOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[rName] + if !ok { + return fmt.Errorf("Not found: %s", rName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Lex bot alias ID is set") + } + + botName := rs.Primary.Attributes["bot_name"] + botAliasName := rs.Primary.Attributes["name"] + + var err error + conn := testAccProvider.Meta().(*AWSClient).lexmodelconn + + output, err = conn.GetBotAlias(&lexmodelbuildingservice.GetBotAliasInput{ + BotName: aws.String(botName), + Name: aws.String(botAliasName), + }) + if tfawserr.ErrCodeEquals(err, lexmodelbuildingservice.ErrCodeNotFoundException) { + return fmt.Errorf("error bot alias '%q' not found", rs.Primary.ID) + } + if err != nil { + return fmt.Errorf("error getting bot alias '%q': %w", rs.Primary.ID, err) + } + + return nil + } +} + +func testAccCheckAwsLexBotAliasDestroy(botName, botAliasName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).lexmodelconn + + _, err := conn.GetBotAlias(&lexmodelbuildingservice.GetBotAliasInput{ + BotName: aws.String(botName), + Name: aws.String(botAliasName), + }) + + if err != nil { + if isAWSErr(err, lexmodelbuildingservice.ErrCodeNotFoundException, "") { + return nil + } + + return fmt.Errorf("error getting bot alias '%s': %s", botAliasName, err) + } + + return fmt.Errorf("error bot alias still exists after delete, %s", botAliasName) + } +} + +func testAccAwsLexBotAliasConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_lex_bot_alias" "test" { + bot_name = aws_lex_bot.test.name + bot_version = aws_lex_bot.test.version + description = "Testing lex bot alias create." + name = "%s" +} +`, rName) +} + +func testAccAwsLexBotAliasConfig_botVersionUpdate(rName string) string { + return fmt.Sprintf(` +resource "aws_lex_bot_alias" "test" { + bot_name = aws_lex_bot.test.name + bot_version = "1" + description = "Testing lex bot alias create." + name = "%s" +} +`, rName) +} + +func testAccAwsLexBotAliasConfig_conversationLogsTextSetup(rName string) string { + return fmt.Sprintf(` +data "aws_iam_policy_document" "lex_assume_role_policy" { + statement { + effect = "Allow" + actions = ["sts:AssumeRole"] + principals { + type = "Service" + identifiers = ["lex.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "test" { + name = "%[1]s" + assume_role_policy = data.aws_iam_policy_document.lex_assume_role_policy.json +} + +data "aws_iam_policy_document" "lex_cloud_watch_logs_policy" { + statement { + effect = "Allow" + actions = [ + "logs:CreateLogStream", + "logs:PutLogEvents", + ] + resources = [ + aws_cloudwatch_log_group.test.arn, + ] + } +} + +resource "aws_iam_role_policy" "test" { + name = "%[1]s" + role = aws_iam_role.test.id + policy = data.aws_iam_policy_document.lex_cloud_watch_logs_policy.json +} + +resource "aws_cloudwatch_log_group" "test" { + name = "%[1]s" +} +`, rName) +} + +func testAccAwsLexBotAliasConfig_conversationLogsText(rName string) string { + return fmt.Sprintf(` +resource "aws_lex_bot_alias" "test" { + bot_name = aws_lex_bot.test.name + bot_version = aws_lex_bot.test.version + description = "Testing lex bot alias create." + name = "%[1]s" + conversation_logs { + iam_role_arn = aws_iam_role.test.arn + log_settings { + destination = "CLOUDWATCH_LOGS" + log_type = "TEXT" + resource_arn = aws_cloudwatch_log_group.test.arn + } + } +} +`, rName) +} + +func testAccAwsLexBotAliasConfig_conversationLogsAudioSetup(rName string) string { + return fmt.Sprintf(` +data "aws_iam_policy_document" "lex_assume_role_policy" { + statement { + effect = "Allow" + actions = ["sts:AssumeRole"] + principals { + type = "Service" + identifiers = ["lex.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "test" { + name = "%[1]s" + assume_role_policy = data.aws_iam_policy_document.lex_assume_role_policy.json +} + +data "aws_iam_policy_document" "lex_s3_policy" { + statement { + effect = "Allow" + actions = [ + "s3:PutObject", + ] + resources = [ + aws_s3_bucket.test.arn, + ] + } +} + +resource "aws_iam_role_policy" "test" { + name = "%[1]s" + role = aws_iam_role.test.id + policy = data.aws_iam_policy_document.lex_s3_policy.json +} + +resource "aws_s3_bucket" "test" { + bucket = "%[1]s" +} +`, rName) +} + +func testAccAwsLexBotAliasConfig_conversationLogsAudio(rName string) string { + return fmt.Sprintf(` +resource "aws_lex_bot_alias" "test" { + bot_name = aws_lex_bot.test.name + bot_version = aws_lex_bot.test.version + description = "Testing lex bot alias create." + name = "%[1]s" + conversation_logs { + iam_role_arn = aws_iam_role.test.arn + log_settings { + destination = "S3" + log_type = "AUDIO" + resource_arn = aws_s3_bucket.test.arn + } + } +} +`, rName) +} + +func testAccAwsLexBotAliasConfig_descriptionUpdate(rName string) string { + return fmt.Sprintf(` +resource "aws_lex_bot_alias" "test" { + bot_name = aws_lex_bot.test.name + bot_version = aws_lex_bot.test.version + description = "Testing lex bot alias update." + name = "%s" +} +`, rName) +} diff --git a/website/docs/d/lex_bot_alias.html.markdown b/website/docs/d/lex_bot_alias.html.markdown new file mode 100644 index 000000000000..4669fc501b55 --- /dev/null +++ b/website/docs/d/lex_bot_alias.html.markdown @@ -0,0 +1,40 @@ +--- +subcategory: "Lex" +layout: "aws" +page_title: "AWS: aws_lex_bot_alias" +description: |- + Provides details about a specific Lex Bot Alias +--- + +# Data Source: aws_lex_bot_alias + +Provides details about a specific Amazon Lex Bot Alias. + +## Example Usage + +```hcl +data "aws_lex_bot_alias" "order_flowers_prod" { + bot_name = "OrderFlowers" + name = "OrderFlowersProd" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `bot_name` - (Required) The name of the bot. +* `name` - (Required) The name of the bot alias. The name is case sensitive. + +## Attributes Reference + +The following attributes are exported. + +* `arn` - The ARN of the bot alias. +* `bot_name` - The name of the bot. +* `bot_version` - The version of the bot that the alias points to. +* `checksum` - Checksum of the bot alias. +* `created_date` - The date that the bot alias was created. +* `description` - A description of the alias. +* `last_updated_date` - The date that the bot alias was updated. When you create a resource, the creation date and the last updated date are the same. +* `name` - The name of the alias. The name is not case sensitive. diff --git a/website/docs/r/lex_bot.html.markdown b/website/docs/r/lex_bot.html.markdown index 04d7401909fc..14cda9c42f59 100644 --- a/website/docs/r/lex_bot.html.markdown +++ b/website/docs/r/lex_bot.html.markdown @@ -62,7 +62,7 @@ The following arguments are supported: * `enable_model_improvements` - (Optional) Set to `true` to enable access to natural language understanding improvements. When you set the `enable_model_improvements` parameter to true you can use the `nlu_intent_confidence_threshold` parameter to configure confidence scores. For more information, see [Confidence Scores](https://docs.aws.amazon.com/lex/latest/dg/confidence-scores.html). You can only set the `enable_model_improvements` parameter in certain Regions. If you set the parameter to true, your bot has access to accuracy improvements. For more information see the [Amazon Lex Bot PutBot API Docs](https://docs.aws.amazon.com/lex/latest/dg/API_PutBot.html#lex-PutBot-request-enableModelImprovements). * `idle_session_ttl_in_seconds` - (Optional) The maximum time in seconds that Amazon Lex retains the data gathered in a conversation. Default is `300`. * `locale` - (Optional) Specifies the target locale for the bot. Any intent used in the bot must be compatible with the locale of the bot. For available locales, see [Amazon Lex Bot PutBot API Docs](https://docs.aws.amazon.com/lex/latest/dg/API_PutBot.html#lex-PutBot-request-locale). Default is `en-US`. -* `intent` - (Required) A set of Intent objects. Each intent represents a command that a user can express. Attributes are documented under [intent](#intent-1). +* `intent` - (Required) A set of Intent objects. Each intent represents a command that a user can express. Attributes are documented under [intent](#intent). * `name` - (Required) The name of the bot that you want to create, case sensitive. * `nlu_intent_confidence_threshold` - (Optional) Determines the threshold where Amazon Lex will insert the AMAZON.FallbackIntent, AMAZON.KendraSearchIntent, or both when returning alternative intents in a PostContent or PostText response. AMAZON.FallbackIntent and AMAZON.KendraSearchIntent are only inserted if they are configured for the bot. For more information see [Amazon Lex Bot PutBot API Docs](https://docs.aws.amazon.com/lex/latest/dg/API_PutBot.html#lex-PutBot-request-nluIntentConfidenceThreshold) This value requires `enable_model_improvements` to be set to `true` and the default is `0`. * `process_behavior` - (Optional) If you set the `process_behavior` element to `BUILD`, Amazon Lex builds the bot so that it can be run. If you set the element to `SAVE` Amazon Lex saves the bot, but doesn't build it. Default is `SAVE`. @@ -93,7 +93,7 @@ Lex chooses one of the messages to use to prompt the user. * `max_attempts` - (Required) The number of times to prompt the user for information. * `message` - (Required) A set of messages, each of which provides a message string and its type. You can specify the message string in plain text or in Speech Synthesis Markup Language (SSML). -Attributes are documented under [message](#message-2). +Attributes are documented under [message](#message). * `response_card` - (Optional) The response card. Amazon Lex will substitute session attributes and slot values into the response card. For more information, see [Example: Using a Response Card](https://docs.aws.amazon.com/lex/latest/dg/ex-resp-card.html). @@ -105,7 +105,7 @@ convey information to the user. At runtime, Amazon Lex selects the message to co * `message` - (Required) A set of messages, each of which provides a message string and its type. You can specify the message string in plain text or in Speech Synthesis Markup Language (SSML). Attributes -are documented under [message](#message-2). +are documented under [message](#message). * `response_card` - (Optional) The response card. Amazon Lex will substitute session attributes and slot values into the response card. For more information, see [Example: Using a Response Card](https://docs.aws.amazon.com/lex/latest/dg/ex-resp-card.html). diff --git a/website/docs/r/lex_bot_alias.html.markdown b/website/docs/r/lex_bot_alias.html.markdown new file mode 100644 index 000000000000..157aca1d08f3 --- /dev/null +++ b/website/docs/r/lex_bot_alias.html.markdown @@ -0,0 +1,74 @@ +--- +subcategory: "Lex" +layout: "aws" +page_title: "AWS: aws_lex_bot_alias" +description: |- + Provides an Amazon Lex Bot Alias resource. +--- + +# Resource: aws_lex_bot_alias + +Provides an Amazon Lex Bot Alias resource. For more information see +[Amazon Lex: How It Works](https://docs.aws.amazon.com/lex/latest/dg/how-it-works.html) + +## Example Usage + +```hcl +resource "aws_lex_bot_alias" "order_flowers_prod" { + bot_name = "OrderFlowers" + bot_version = "1" + description = "Production Version of the OrderFlowers Bot." + name = "OrderFlowersProd" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `bot_name` - (Required) The name of the bot. +* `bot_version` - (Required) The name of the bot. +* `conversation_logs` - (Optional) The settings that determine how Amazon Lex uses conversation logs for the alias. Attributes are documented under [conversation_logs](#conversation_logs). +* `description` - (Optional) A description of the alias. +* `name` - (Required) The name of the alias. The name is not case sensitive. + +### conversation_logs + +Contains information about conversation log settings. + +* `iam_role_arn` - (Required) The Amazon Resource Name (ARN) of the IAM role used to write your logs to CloudWatch Logs or an S3 bucket. +* `log_settings` - (Optional) The settings for your conversation logs. You can log text, audio, or both. Attributes are documented under [log_settings](#log_settings). + +### log_settings + +The settings for conversation logs. + +* `destination` - (Required) The destination where logs are delivered. Options are `CLOUDWATCH_LOGS` or `S3`. +* `kms_key_arn` - (Optional) The Amazon Resource Name (ARN) of the key used to encrypt audio logs in an S3 bucket. This can only be specified when `destination` is set to `S3`. +* `log_type` - (Required) The type of logging that is enabled. Options are `AUDIO` or `TEXT`. +* `resource_arn` - (Required) The Amazon Resource Name (ARN) of the CloudWatch Logs log group or S3 bucket where the logs are delivered. + +### Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 1 mins) Used when creating the bot alias +* `update` - (Defaults to 1 mins) Used when updating the bot alias +* `delete` - (Defaults to 5 mins) Used when deleting the bot alias + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `arn` - The ARN of the bot alias. +* `checksum` - Checksum of the bot alias. +* `created_date` - The date that the bot alias was created. +* `last_updated_date` - The date that the bot alias was updated. When you create a resource, the creation date and the last updated date are the same. + +## Import + +Bot aliases can be imported using an ID with the format `bot_name:bot_alias_name`. + +``` +$ terraform import aws_lex_bot_alias.order_flowers_prod OrderFlowers:OrderFlowersProd +``` diff --git a/website/docs/r/lex_intent.html.markdown b/website/docs/r/lex_intent.html.markdown index 4be22a63f23a..084fb7939ca0 100644 --- a/website/docs/r/lex_intent.html.markdown +++ b/website/docs/r/lex_intent.html.markdown @@ -119,38 +119,25 @@ resource "aws_lex_intent" "order_flowers_intent" { The following arguments are supported: * `conclusion_statement` - (Optional) The statement that you want Amazon Lex to convey to the user -after the intent is successfully fulfilled by the Lambda function. - -This element is relevant only if you provide a Lambda function in the `fulfillment_activity`. If you -return the intent to the client application, you can't specify this element. - -The `follow_up_prompt` and `conclusion_statement` are mutually exclusive. You can specify only one. - -Attributes are documented under [statement](#statement). - +after the intent is successfully fulfilled by the Lambda function. This element is relevant only if +you provide a Lambda function in the `fulfillment_activity`. If you return the intent to the client +application, you can't specify this element. The `follow_up_prompt` and `conclusion_statement` are +mutually exclusive. You can specify only one. Attributes are documented under [statement](#statement). * `confirmation_prompt` - (Optional) Prompts the user to confirm the intent. This question should have a yes or no answer. You you must provide both the `rejection_statement` and `confirmation_prompt`, -or neither. Attributes are documented under [prompt](#prompt-1). +or neither. Attributes are documented under [prompt](#prompt). * `create_version` - (Optional) Determines if a new slot type version is created when the initial -resource is created and on each update. Defaults to true. +resource is created and on each update. Defaults to `false`. * `description` - (Optional) A description of the intent. * `dialog_code_hook` - (Optional) Specifies a Lambda function to invoke for each user input. You can -invoke this Lambda function to personalize user interaction. Attributes are documented under [code_hook](#code_hook-1). +invoke this Lambda function to personalize user interaction. Attributes are documented under [code_hook](#code_hook). * `follow_up_prompt` - (Optional) Amazon Lex uses this prompt to solicit additional activity after fulfilling an intent. For example, after the OrderPizza intent is fulfilled, you might prompt the -user to order a drink. - -The `follow_up_prompt` field and the `conclusion_statement` field are mutually exclusive. You can -specify only one. - -Attributes are documented under [follow_up_prompt](#follow_up_prompt-1). - -* `fulfillment_activity` - (Optional) Describes how the intent is fulfilled. For example, after a +user to order a drink. The `follow_up_prompt` field and the `conclusion_statement` field are mutually +exclusive. You can specify only one. Attributes are documented under [follow_up_prompt](#follow_up_prompt). +* `fulfillment_activity` - (Required) Describes how the intent is fulfilled. For example, after a user provides all of the information for a pizza order, `fulfillment_activity` defines how the bot -places an order with a local pizza store. - -Attributes are documented under [fulfillment_activity](#fulfillment_activity-1). - +places an order with a local pizza store. Attributes are documented under [fulfillment_activity](#fulfillment_activity). * `name` - (Required) The name of the intent, not case sensitive. * `parent_intent_signature` - (Optional) A unique identifier for the built-in intent to base this intent on. To find the signature for an intent, see @@ -158,19 +145,13 @@ intent on. To find the signature for an intent, see in the Alexa Skills Kit. * `rejection_statement` - (Optional) When the user answers "no" to the question defined in `confirmation_prompt`, Amazon Lex responds with this statement to acknowledge that the intent was -canceled. - -You must provide both the `rejection_statement` and the `confirmation_prompt`, or neither. - +canceled. You must provide both the `rejection_statement` and the `confirmation_prompt`, or neither. Attributes are documented under [statement](#statement). - * `sample_utterances` - (Optional) An array of utterances (strings) that a user might say to signal the intent. For example, "I want {PizzaSize} pizza", "Order {Quantity} {PizzaSize} pizzas". - In each utterance, a slot name is enclosed in curly braces. - * `slot` - (Optional) An list of intent slots. At runtime, Amazon Lex elicits required slot values -from the user using prompts defined in the slots. Attributes are documented under [slot](#slot-1). +from the user using prompts defined in the slots. Attributes are documented under [slot](#slot). ### code_hook @@ -186,7 +167,7 @@ to invoke your Lambda function. For more information, see A prompt for additional activity after an intent is fulfilled. For example, after the OrderPizza intent is fulfilled, you might prompt the user to find out whether the user wants to order drinks. -* `prompt` - (Required) Prompts for information from the user. Attributes are documented under [prompt](#prompt-1). +* `prompt` - (Required) Prompts for information from the user. Attributes are documented under [prompt](#prompt). * `rejectionStatement` - (Optional) If the user answers "no" to the question defined in the prompt field, Amazon Lex responds with this statement to acknowledge that the intent was canceled. Attributes are documented below under [statement](#statement). @@ -198,7 +179,7 @@ Describes how the intent is fulfilled after the user provides all of the informa * `type` - (Required) How the intent should be fulfilled, either by running a Lambda function or by returning the slot data to the client application. * `code_hook` - (Optional) A description of the Lambda function that is run to fulfill the intent. -Required if type is CodeHook. Attributes are documented under [code_hook](#code_hook-1). +Required if type is CodeHook. Attributes are documented under [code_hook](#code_hook). ### message @@ -218,7 +199,7 @@ Lex chooses one of the messages to use to prompt the user. * `max_attempts` - (Required) The number of times to prompt the user for information. * `message` - (Required) A set of messages, each of which provides a message string and its type. You can specify the message string in plain text or in Speech Synthesis Markup Language (SSML). -Attributes are documented under [message](#message-1). +Attributes are documented under [message](#message). * `response_card` - (Optional) The response card. Amazon Lex will substitute session attributes and slot values into the response card. For more information, see [Example: Using a Response Card](https://docs.aws.amazon.com/lex/latest/dg/ex-resp-card.html). @@ -232,10 +213,8 @@ Identifies the version of a specific slot. * `description` - (Optional) A description of the bot. * `priority` - (Optional) Directs Lex the order in which to elicit this slot value from the user. For example, if the intent has two slots with priorities 1 and 2, AWS Lex first elicits a value for -the slot with priority 1. - -If multiple slots share the same priority, the order in which Lex elicits values is arbitrary. - +the slot with priority 1. If multiple slots share the same priority, the order in which Lex elicits +values is arbitrary. * `response_card` - (Optional) The response card. Amazon Lex will substitute session attributes and slot values into the response card. For more information, see [Example: Using a Response Card](https://docs.aws.amazon.com/lex/latest/dg/ex-resp-card.html). @@ -246,7 +225,7 @@ is optional. In most cases, Amazon Lex is capable of understanding user utteranc the built-in slot types. * `slot_type_version` - (Optional) The version of the slot type. * `value_elicitation_prompt` - (Optional) The prompt that Amazon Lex uses to elicit the slot value -from the user. Attributes are documented under [prompt](#prompt-1). +from the user. Attributes are documented under [prompt](#prompt). ### statement @@ -255,7 +234,7 @@ convey information to the user. At runtime, Amazon Lex selects the message to co * `message` - (Required) A set of messages, each of which provides a message string and its type. You can specify the message string in plain text or in Speech Synthesis Markup Language (SSML). -Attributes are documented under [message](#message-1). +Attributes are documented under [message](#message). * `response_card` - (Optional) The response card. Amazon Lex will substitute session attributes and slot values into the response card. For more information, see [Example: Using a Response Card](https://docs.aws.amazon.com/lex/latest/dg/ex-resp-card.html). diff --git a/website/docs/r/lex_slot_type.html.markdown b/website/docs/r/lex_slot_type.html.markdown index e62e578f3f8c..d25749301dc3 100644 --- a/website/docs/r/lex_slot_type.html.markdown +++ b/website/docs/r/lex_slot_type.html.markdown @@ -15,7 +15,7 @@ Provides an Amazon Lex Slot Type resource. For more information see ```hcl resource "aws_lex_slot_type" "flower_types" { - create_version = false + create_version = true description = "Types of flowers to order" enumeration_value { @@ -48,16 +48,16 @@ The following arguments are supported: * `enumeration_value` - (Required) A list of EnumerationValue objects that defines the values that the slot type can take. Each value can have a list of synonyms, which are additional values that help train the machine learning model about the values that it resolves for a slot. Attributes are -documented under [enumeration_value](#enumeration_value-1). +documented under [enumeration_value](#enumeration_value). * `name` - (Required) The name of the slot type. The name is not case sensitive. * `create_version` - (Optional) Determines if a new slot type version is created when the initial resource is created and on each -update. Defaults to true. +update. Defaults to `false`. * `description` - (Optional) A description of the slot type. * `value_selection_strategy` - (Optional) Determines the slot resolution strategy that Amazon Lex uses to return slot type values. `ORIGINAL_VALUE` returns the value entered by the user if the user value is similar to the slot value. `TOP_RESOLUTION` returns the first value in the resolution list -if there is a resolution list for the slot, otherwise null is returned. +if there is a resolution list for the slot, otherwise null is returned. Defaults to `ORIGINAL_VALUE`. ### enumeration_value