From af56a1f697f16dae026acc123697cd3deaf0dea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20Lindstr=C3=B6m?= Date: Mon, 8 Oct 2018 15:14:05 +0200 Subject: [PATCH] Add lb authentication support --- aws/resource_aws_lb_listener.go | 460 +++++++++++++++--- aws/resource_aws_lb_listener_rule.go | 335 ++++++++++++- aws/resource_aws_lb_listener_rule_test.go | 422 ++++++++++++++++ aws/resource_aws_lb_listener_test.go | 357 ++++++++++++++ aws/structure.go | 15 + website/docs/r/lb_listener.html.markdown | 30 ++ website/docs/r/lb_listener_rule.html.markdown | 32 ++ 7 files changed, 1577 insertions(+), 74 deletions(-) diff --git a/aws/resource_aws_lb_listener.go b/aws/resource_aws_lb_listener.go index 928b2a5cb87..5c8aa5949e4 100644 --- a/aws/resource_aws_lb_listener.go +++ b/aws/resource_aws_lb_listener.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "regexp" + "strconv" "strings" "time" @@ -71,18 +72,24 @@ func resourceAwsLbListener() *schema.Resource { "default_action": { Type: schema.TypeList, Required: true, - MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{ + elbv2.ActionTypeEnumAuthenticateCognito, + elbv2.ActionTypeEnumAuthenticateOidc, elbv2.ActionTypeEnumFixedResponse, elbv2.ActionTypeEnumForward, elbv2.ActionTypeEnumRedirect, }, true), }, + "order": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 50000), + }, "target_group_arn": { Type: schema.TypeString, @@ -177,6 +184,123 @@ func resourceAwsLbListener() *schema.Resource { }, }, }, + + "authenticate_cognito": { + Type: schema.TypeList, + Optional: true, + DiffSuppressFunc: suppressIfDefaultActionTypeNot("authenticate-cognito"), + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authentication_request_extra_params": { + Type: schema.TypeMap, + Optional: true, + }, + "on_unauthenticated_request": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + elbv2.AuthenticateCognitoActionConditionalBehaviorEnumDeny, + elbv2.AuthenticateCognitoActionConditionalBehaviorEnumAllow, + elbv2.AuthenticateCognitoActionConditionalBehaviorEnumAuthenticate, + }, true), + }, + "scope": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_cookie_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "user_pool_arn": { + Type: schema.TypeString, + Required: true, + }, + "user_pool_client_id": { + Type: schema.TypeString, + Required: true, + }, + "user_pool_domain": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "authenticate_oidc": { + Type: schema.TypeList, + Optional: true, + DiffSuppressFunc: suppressIfDefaultActionTypeNot("authenticate-oidc"), + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authentication_request_extra_params": { + Type: schema.TypeMap, + Optional: true, + }, + "authorization_endpoint": { + Type: schema.TypeString, + Required: true, + }, + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "issuer": { + Type: schema.TypeString, + Required: true, + }, + "on_unauthenticated_request": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + elbv2.AuthenticateOidcActionConditionalBehaviorEnumDeny, + elbv2.AuthenticateOidcActionConditionalBehaviorEnumAllow, + elbv2.AuthenticateOidcActionConditionalBehaviorEnumAuthenticate, + }, true), + }, + "scope": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_cookie_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "token_endpoint": { + Type: schema.TypeString, + Required: true, + }, + "user_info_endpoint": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, }, }, }, @@ -221,56 +345,132 @@ func resourceAwsLbListenerCreate(d *schema.ResourceData, meta interface{}) error } } - if defaultActions := d.Get("default_action").([]interface{}); len(defaultActions) == 1 { - params.DefaultActions = make([]*elbv2.Action, len(defaultActions)) + defaultActions := d.Get("default_action").([]interface{}) + params.DefaultActions = make([]*elbv2.Action, len(defaultActions)) + for i, defaultAction := range defaultActions { + defaultActionMap := defaultAction.(map[string]interface{}) - for i, defaultAction := range defaultActions { - defaultActionMap := defaultAction.(map[string]interface{}) + action := &elbv2.Action{ + Type: aws.String(defaultActionMap["type"].(string)), + } - action := &elbv2.Action{ - Type: aws.String(defaultActionMap["type"].(string)), - } + if order, ok := defaultActionMap["order"]; ok && order != 0 { + action.Order = aws.Int64(int64(order.(int))) + } + if len(defaultActions) != 1 && action.Order == nil { + return errors.New("when using more then one action, you need to specify 'order' for each action") + } - switch defaultActionMap["type"].(string) { - case "forward": - action.TargetGroupArn = aws.String(defaultActionMap["target_group_arn"].(string)) + switch defaultActionMap["type"].(string) { + case "forward": + action.TargetGroupArn = aws.String(defaultActionMap["target_group_arn"].(string)) - case "redirect": - redirectList := defaultActionMap["redirect"].([]interface{}) + case "redirect": + redirectList := defaultActionMap["redirect"].([]interface{}) - if len(redirectList) == 1 { - redirectMap := redirectList[0].(map[string]interface{}) + if len(redirectList) == 1 { + redirectMap := redirectList[0].(map[string]interface{}) - action.RedirectConfig = &elbv2.RedirectActionConfig{ - Host: aws.String(redirectMap["host"].(string)), - Path: aws.String(redirectMap["path"].(string)), - Port: aws.String(redirectMap["port"].(string)), - Protocol: aws.String(redirectMap["protocol"].(string)), - Query: aws.String(redirectMap["query"].(string)), - StatusCode: aws.String(redirectMap["status_code"].(string)), - } - } else { - return errors.New("for actions of type 'redirect', you must specify a 'redirect' block") + action.RedirectConfig = &elbv2.RedirectActionConfig{ + Host: aws.String(redirectMap["host"].(string)), + Path: aws.String(redirectMap["path"].(string)), + Port: aws.String(redirectMap["port"].(string)), + Protocol: aws.String(redirectMap["protocol"].(string)), + Query: aws.String(redirectMap["query"].(string)), + StatusCode: aws.String(redirectMap["status_code"].(string)), } + } else { + return errors.New("for actions of type 'redirect', you must specify a 'redirect' block") + } - case "fixed-response": - fixedResponseList := defaultActionMap["fixed_response"].([]interface{}) + case "fixed-response": + fixedResponseList := defaultActionMap["fixed_response"].([]interface{}) - if len(fixedResponseList) == 1 { - fixedResponseMap := fixedResponseList[0].(map[string]interface{}) + if len(fixedResponseList) == 1 { + fixedResponseMap := fixedResponseList[0].(map[string]interface{}) - action.FixedResponseConfig = &elbv2.FixedResponseActionConfig{ - ContentType: aws.String(fixedResponseMap["content_type"].(string)), - MessageBody: aws.String(fixedResponseMap["message_body"].(string)), - StatusCode: aws.String(fixedResponseMap["status_code"].(string)), - } - } else { - return errors.New("for actions of type 'fixed-response', you must specify a 'fixed_response' block") + action.FixedResponseConfig = &elbv2.FixedResponseActionConfig{ + ContentType: aws.String(fixedResponseMap["content_type"].(string)), + MessageBody: aws.String(fixedResponseMap["message_body"].(string)), + StatusCode: aws.String(fixedResponseMap["status_code"].(string)), } + } else { + return errors.New("for actions of type 'fixed-response', you must specify a 'fixed_response' block") } - params.DefaultActions[i] = action + case elbv2.ActionTypeEnumAuthenticateCognito: + authenticateCognitoList := defaultActionMap["authenticate_cognito"].([]interface{}) + + if len(authenticateCognitoList) == 1 { + authenticateCognitoMap := authenticateCognitoList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateCognitoMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateCognitoConfig = &elbv2.AuthenticateCognitoActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + UserPoolArn: aws.String(authenticateCognitoMap["user_pool_arn"].(string)), + UserPoolClientId: aws.String(authenticateCognitoMap["user_pool_client_id"].(string)), + UserPoolDomain: aws.String(authenticateCognitoMap["user_pool_domain"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateCognitoMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateCognitoConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateCognitoMap["scope"]; ok && scope != "" { + action.AuthenticateCognitoConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateCognitoMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateCognitoConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateCognitoMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateCognitoConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-cognito', you must specify a 'authenticate_cognito' block") + } + + case elbv2.ActionTypeEnumAuthenticateOidc: + authenticateOidcList := defaultActionMap["authenticate_oidc"].([]interface{}) + + if len(authenticateOidcList) == 1 { + authenticateOidcMap := authenticateOidcList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateOidcMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateOidcConfig = &elbv2.AuthenticateOidcActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + AuthorizationEndpoint: aws.String(authenticateOidcMap["authorization_endpoint"].(string)), + ClientId: aws.String(authenticateOidcMap["client_id"].(string)), + ClientSecret: aws.String(authenticateOidcMap["client_secret"].(string)), + Issuer: aws.String(authenticateOidcMap["issuer"].(string)), + TokenEndpoint: aws.String(authenticateOidcMap["token_endpoint"].(string)), + UserInfoEndpoint: aws.String(authenticateOidcMap["user_info_endpoint"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateOidcMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateOidcConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateOidcMap["scope"]; ok && scope != "" { + action.AuthenticateOidcConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateOidcMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateOidcConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateOidcMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateOidcConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-oidc', you must specify a 'authenticate_oidc' block") + } } + + params.DefaultActions[i] = action } var resp *elbv2.CreateListenerOutput @@ -332,40 +532,84 @@ func resourceAwsLbListenerRead(d *schema.ResourceData, meta interface{}) error { d.Set("certificate_arn", listener.Certificates[0].CertificateArn) } - defaultActions := make([]map[string]interface{}, 0) - if listener.DefaultActions != nil && len(listener.DefaultActions) > 0 { - for _, defaultAction := range listener.DefaultActions { - defaultActionMap := make(map[string]interface{}) - defaultActionMap["type"] = aws.StringValue(defaultAction.Type) + sortedActions := sortActionsBasedonTypeinTFFile("default_action", listener.DefaultActions, d) + defaultActions := make([]interface{}, len(sortedActions)) + for i, defaultAction := range sortedActions { + defaultActionMap := make(map[string]interface{}) + defaultActionMap["type"] = aws.StringValue(defaultAction.Type) + defaultActionMap["order"] = aws.Int64Value(defaultAction.Order) + + switch aws.StringValue(defaultAction.Type) { + case "forward": + defaultActionMap["target_group_arn"] = aws.StringValue(defaultAction.TargetGroupArn) + + case "redirect": + defaultActionMap["redirect"] = []map[string]interface{}{ + { + "host": aws.StringValue(defaultAction.RedirectConfig.Host), + "path": aws.StringValue(defaultAction.RedirectConfig.Path), + "port": aws.StringValue(defaultAction.RedirectConfig.Port), + "protocol": aws.StringValue(defaultAction.RedirectConfig.Protocol), + "query": aws.StringValue(defaultAction.RedirectConfig.Query), + "status_code": aws.StringValue(defaultAction.RedirectConfig.StatusCode), + }, + } - switch aws.StringValue(defaultAction.Type) { - case "forward": - defaultActionMap["target_group_arn"] = aws.StringValue(defaultAction.TargetGroupArn) + case "fixed-response": + defaultActionMap["fixed_response"] = []map[string]interface{}{ + { + "content_type": aws.StringValue(defaultAction.FixedResponseConfig.ContentType), + "message_body": aws.StringValue(defaultAction.FixedResponseConfig.MessageBody), + "status_code": aws.StringValue(defaultAction.FixedResponseConfig.StatusCode), + }, + } - case "redirect": - defaultActionMap["redirect"] = []map[string]interface{}{ - { - "host": aws.StringValue(defaultAction.RedirectConfig.Host), - "path": aws.StringValue(defaultAction.RedirectConfig.Path), - "port": aws.StringValue(defaultAction.RedirectConfig.Port), - "protocol": aws.StringValue(defaultAction.RedirectConfig.Protocol), - "query": aws.StringValue(defaultAction.RedirectConfig.Query), - "status_code": aws.StringValue(defaultAction.RedirectConfig.StatusCode), - }, - } + case "authenticate-cognito": + authenticationRequestExtraParams := make(map[string]interface{}) + for key, value := range defaultAction.AuthenticateCognitoConfig.AuthenticationRequestExtraParams { + authenticationRequestExtraParams[key] = aws.StringValue(value) + } + defaultActionMap["authenticate_cognito"] = []map[string]interface{}{ + { + "authentication_request_extra_params": authenticationRequestExtraParams, + "on_unauthenticated_request": aws.StringValue(defaultAction.AuthenticateCognitoConfig.OnUnauthenticatedRequest), + "scope": aws.StringValue(defaultAction.AuthenticateCognitoConfig.Scope), + "session_cookie_name": aws.StringValue(defaultAction.AuthenticateCognitoConfig.SessionCookieName), + "session_timeout": aws.Int64Value(defaultAction.AuthenticateCognitoConfig.SessionTimeout), + "user_pool_arn": aws.StringValue(defaultAction.AuthenticateCognitoConfig.UserPoolArn), + "user_pool_client_id": aws.StringValue(defaultAction.AuthenticateCognitoConfig.UserPoolClientId), + "user_pool_domain": aws.StringValue(defaultAction.AuthenticateCognitoConfig.UserPoolDomain), + }, + } - case "fixed-response": - defaultActionMap["fixed_response"] = []map[string]interface{}{ - { - "content_type": aws.StringValue(defaultAction.FixedResponseConfig.ContentType), - "message_body": aws.StringValue(defaultAction.FixedResponseConfig.MessageBody), - "status_code": aws.StringValue(defaultAction.FixedResponseConfig.StatusCode), - }, - } + case "authenticate-oidc": + authenticationRequestExtraParams := make(map[string]interface{}) + for key, value := range defaultAction.AuthenticateOidcConfig.AuthenticationRequestExtraParams { + authenticationRequestExtraParams[key] = aws.StringValue(value) } - defaultActions = append(defaultActions, defaultActionMap) + // The LB API currently provides no way to read the ClientSecret + // Instead we passthrough the configuration value into the state + clientSecret := d.Get("default_action." + strconv.Itoa(i) + ".authenticate_oidc.0.client_secret").(string) + + defaultActionMap["authenticate_oidc"] = []map[string]interface{}{ + { + "authentication_request_extra_params": authenticationRequestExtraParams, + "authorization_endpoint": aws.StringValue(defaultAction.AuthenticateOidcConfig.AuthorizationEndpoint), + "client_id": aws.StringValue(defaultAction.AuthenticateOidcConfig.ClientId), + "client_secret": clientSecret, + "issuer": aws.StringValue(defaultAction.AuthenticateOidcConfig.Issuer), + "on_unauthenticated_request": aws.StringValue(defaultAction.AuthenticateOidcConfig.OnUnauthenticatedRequest), + "scope": aws.StringValue(defaultAction.AuthenticateOidcConfig.Scope), + "session_cookie_name": aws.StringValue(defaultAction.AuthenticateOidcConfig.SessionCookieName), + "session_timeout": aws.Int64Value(defaultAction.AuthenticateOidcConfig.SessionTimeout), + "token_endpoint": aws.StringValue(defaultAction.AuthenticateOidcConfig.TokenEndpoint), + "user_info_endpoint": aws.StringValue(defaultAction.AuthenticateOidcConfig.UserInfoEndpoint), + }, + } } + + defaultActions[i] = defaultActionMap } d.Set("default_action", defaultActions) @@ -392,14 +636,23 @@ func resourceAwsLbListenerUpdate(d *schema.ResourceData, meta interface{}) error } } - if defaultActions := d.Get("default_action").([]interface{}); len(defaultActions) == 1 { + if d.HasChange("default_action") { + defaultActions := d.Get("default_action").([]interface{}) params.DefaultActions = make([]*elbv2.Action, len(defaultActions)) for i, defaultAction := range defaultActions { defaultActionMap := defaultAction.(map[string]interface{}) - action := &elbv2.Action{} - action.Type = aws.String(defaultActionMap["type"].(string)) + action := &elbv2.Action{ + Type: aws.String(defaultActionMap["type"].(string)), + } + + if order, ok := defaultActionMap["order"]; ok && order != 0 { + action.Order = aws.Int64(int64(order.(int))) + } + if len(defaultActions) != 1 && action.Order == nil { + return errors.New("when using more then one action, you need to specify 'order' for each action") + } switch defaultActionMap["type"].(string) { case "forward": @@ -437,6 +690,77 @@ func resourceAwsLbListenerUpdate(d *schema.ResourceData, meta interface{}) error } else { return errors.New("for actions of type 'fixed-response', you must specify a 'fixed_response' block") } + + case "authenticate-cognito": + authenticateCognitoList := defaultActionMap["authenticate_cognito"].([]interface{}) + + if len(authenticateCognitoList) == 1 { + authenticateCognitoMap := authenticateCognitoList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateCognitoMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateCognitoConfig = &elbv2.AuthenticateCognitoActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + UserPoolArn: aws.String(authenticateCognitoMap["user_pool_arn"].(string)), + UserPoolClientId: aws.String(authenticateCognitoMap["user_pool_client_id"].(string)), + UserPoolDomain: aws.String(authenticateCognitoMap["user_pool_domain"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateCognitoMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateCognitoConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateCognitoMap["scope"]; ok && scope != "" { + action.AuthenticateCognitoConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateCognitoMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateCognitoConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateCognitoMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateCognitoConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-cognito', you must specify a 'authenticate_cognito' block") + } + + case "authenticate-oidc": + authenticateOidcList := defaultActionMap["authenticate_oidc"].([]interface{}) + + if len(authenticateOidcList) == 1 { + authenticateOidcMap := authenticateOidcList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateOidcMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateOidcConfig = &elbv2.AuthenticateOidcActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + AuthorizationEndpoint: aws.String(authenticateOidcMap["authorization_endpoint"].(string)), + ClientId: aws.String(authenticateOidcMap["client_id"].(string)), + ClientSecret: aws.String(authenticateOidcMap["client_secret"].(string)), + Issuer: aws.String(authenticateOidcMap["issuer"].(string)), + TokenEndpoint: aws.String(authenticateOidcMap["token_endpoint"].(string)), + UserInfoEndpoint: aws.String(authenticateOidcMap["user_info_endpoint"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateOidcMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateOidcConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateOidcMap["scope"]; ok && scope != "" { + action.AuthenticateOidcConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateOidcMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateOidcConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateOidcMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateOidcConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-oidc', you must specify a 'authenticate_oidc' block") + } } params.DefaultActions[i] = action diff --git a/aws/resource_aws_lb_listener_rule.go b/aws/resource_aws_lb_listener_rule.go index 7eac9c02fc6..e40a16ff26c 100644 --- a/aws/resource_aws_lb_listener_rule.go +++ b/aws/resource_aws_lb_listener_rule.go @@ -53,11 +53,18 @@ func resourceAwsLbbListenerRule() *schema.Resource { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{ + elbv2.ActionTypeEnumAuthenticateCognito, + elbv2.ActionTypeEnumAuthenticateOidc, elbv2.ActionTypeEnumFixedResponse, elbv2.ActionTypeEnumForward, elbv2.ActionTypeEnumRedirect, }, true), }, + "order": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 50000), + }, "target_group_arn": { Type: schema.TypeString, @@ -152,6 +159,123 @@ func resourceAwsLbbListenerRule() *schema.Resource { }, }, }, + + "authenticate_cognito": { + Type: schema.TypeList, + Optional: true, + DiffSuppressFunc: suppressIfDefaultActionTypeNot(elbv2.ActionTypeEnumAuthenticateCognito), + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authentication_request_extra_params": { + Type: schema.TypeMap, + Optional: true, + }, + "on_unauthenticated_request": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + elbv2.AuthenticateCognitoActionConditionalBehaviorEnumDeny, + elbv2.AuthenticateCognitoActionConditionalBehaviorEnumAllow, + elbv2.AuthenticateCognitoActionConditionalBehaviorEnumAuthenticate, + }, true), + }, + "scope": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_cookie_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "user_pool_arn": { + Type: schema.TypeString, + Required: true, + }, + "user_pool_client_id": { + Type: schema.TypeString, + Required: true, + }, + "user_pool_domain": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "authenticate_oidc": { + Type: schema.TypeList, + Optional: true, + DiffSuppressFunc: suppressIfDefaultActionTypeNot(elbv2.ActionTypeEnumAuthenticateOidc), + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authentication_request_extra_params": { + Type: schema.TypeMap, + Optional: true, + }, + "authorization_endpoint": { + Type: schema.TypeString, + Required: true, + }, + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "issuer": { + Type: schema.TypeString, + Required: true, + }, + "on_unauthenticated_request": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + elbv2.AuthenticateOidcActionConditionalBehaviorEnumDeny, + elbv2.AuthenticateOidcActionConditionalBehaviorEnumAllow, + elbv2.AuthenticateOidcActionConditionalBehaviorEnumAuthenticate, + }, true), + }, + "scope": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_cookie_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "session_timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "token_endpoint": { + Type: schema.TypeString, + Required: true, + }, + "user_info_endpoint": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, }, }, }, @@ -206,8 +330,16 @@ func resourceAwsLbListenerRuleCreate(d *schema.ResourceData, meta interface{}) e for i, action := range actions { actionMap := action.(map[string]interface{}) - action := &elbv2.Action{} - action.Type = aws.String(actionMap["type"].(string)) + action := &elbv2.Action{ + Type: aws.String(actionMap["type"].(string)), + } + + if order, ok := actionMap["order"]; ok && order != 0 { + action.Order = aws.Int64(int64(order.(int))) + } + if len(actions) != 1 && action.Order == nil { + return errors.New("when using more then one action, you need to specify 'order' for each action") + } switch actionMap["type"].(string) { case "forward": @@ -245,6 +377,77 @@ func resourceAwsLbListenerRuleCreate(d *schema.ResourceData, meta interface{}) e } else { return errors.New("for actions of type 'fixed-response', you must specify a 'fixed_response' block") } + + case "authenticate-cognito": + authenticateCognitoList := actionMap["authenticate_cognito"].([]interface{}) + + if len(authenticateCognitoList) == 1 { + authenticateCognitoMap := authenticateCognitoList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateCognitoMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateCognitoConfig = &elbv2.AuthenticateCognitoActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + UserPoolArn: aws.String(authenticateCognitoMap["user_pool_arn"].(string)), + UserPoolClientId: aws.String(authenticateCognitoMap["user_pool_client_id"].(string)), + UserPoolDomain: aws.String(authenticateCognitoMap["user_pool_domain"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateCognitoMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateCognitoConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateCognitoMap["scope"]; ok && scope != "" { + action.AuthenticateCognitoConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateCognitoMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateCognitoConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateCognitoMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateCognitoConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-cognito', you must specify a 'authenticate_cognito' block") + } + + case "authenticate-oidc": + authenticateOidcList := actionMap["authenticate_oidc"].([]interface{}) + + if len(authenticateOidcList) == 1 { + authenticateOidcMap := authenticateOidcList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateOidcMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateOidcConfig = &elbv2.AuthenticateOidcActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + AuthorizationEndpoint: aws.String(authenticateOidcMap["authorization_endpoint"].(string)), + ClientId: aws.String(authenticateOidcMap["client_id"].(string)), + ClientSecret: aws.String(authenticateOidcMap["client_secret"].(string)), + Issuer: aws.String(authenticateOidcMap["issuer"].(string)), + TokenEndpoint: aws.String(authenticateOidcMap["token_endpoint"].(string)), + UserInfoEndpoint: aws.String(authenticateOidcMap["user_info_endpoint"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateOidcMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateOidcConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateOidcMap["scope"]; ok && scope != "" { + action.AuthenticateOidcConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateOidcMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateOidcConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateOidcMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateOidcConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-oidc', you must specify a 'authenticate_oidc' block") + } } params.Actions[i] = action @@ -340,10 +543,12 @@ func resourceAwsLbListenerRuleRead(d *schema.ResourceData, meta interface{}) err } } - actions := make([]interface{}, len(rule.Actions)) - for i, action := range rule.Actions { + sortedActions := sortActionsBasedonTypeinTFFile("action", rule.Actions, d) + actions := make([]interface{}, len(sortedActions)) + for i, action := range sortedActions { actionMap := make(map[string]interface{}) actionMap["type"] = aws.StringValue(action.Type) + actionMap["order"] = aws.Int64Value(action.Order) switch actionMap["type"] { case "forward": @@ -369,6 +574,51 @@ func resourceAwsLbListenerRuleRead(d *schema.ResourceData, meta interface{}) err "status_code": aws.StringValue(action.FixedResponseConfig.StatusCode), }, } + + case "authenticate-cognito": + authenticationRequestExtraParams := make(map[string]interface{}) + for key, value := range action.AuthenticateCognitoConfig.AuthenticationRequestExtraParams { + authenticationRequestExtraParams[key] = aws.StringValue(value) + } + + actionMap["authenticate_cognito"] = []map[string]interface{}{ + { + "authentication_request_extra_params": authenticationRequestExtraParams, + "on_unauthenticated_request": aws.StringValue(action.AuthenticateCognitoConfig.OnUnauthenticatedRequest), + "scope": aws.StringValue(action.AuthenticateCognitoConfig.Scope), + "session_cookie_name": aws.StringValue(action.AuthenticateCognitoConfig.SessionCookieName), + "session_timeout": aws.Int64Value(action.AuthenticateCognitoConfig.SessionTimeout), + "user_pool_arn": aws.StringValue(action.AuthenticateCognitoConfig.UserPoolArn), + "user_pool_client_id": aws.StringValue(action.AuthenticateCognitoConfig.UserPoolClientId), + "user_pool_domain": aws.StringValue(action.AuthenticateCognitoConfig.UserPoolDomain), + }, + } + + case "authenticate-oidc": + authenticationRequestExtraParams := make(map[string]interface{}) + for key, value := range action.AuthenticateOidcConfig.AuthenticationRequestExtraParams { + authenticationRequestExtraParams[key] = aws.StringValue(value) + } + + // The LB API currently provides no way to read the ClientSecret + // Instead we passthrough the configuration value into the state + clientSecret := d.Get("action." + strconv.Itoa(i) + ".authenticate_oidc.0.client_secret").(string) + + actionMap["authenticate_oidc"] = []map[string]interface{}{ + { + "authentication_request_extra_params": authenticationRequestExtraParams, + "authorization_endpoint": aws.StringValue(action.AuthenticateOidcConfig.AuthorizationEndpoint), + "client_id": aws.StringValue(action.AuthenticateOidcConfig.ClientId), + "client_secret": clientSecret, + "issuer": aws.StringValue(action.AuthenticateOidcConfig.Issuer), + "on_unauthenticated_request": aws.StringValue(action.AuthenticateOidcConfig.OnUnauthenticatedRequest), + "scope": aws.StringValue(action.AuthenticateOidcConfig.Scope), + "session_cookie_name": aws.StringValue(action.AuthenticateOidcConfig.SessionCookieName), + "session_timeout": aws.Int64Value(action.AuthenticateOidcConfig.SessionTimeout), + "token_endpoint": aws.StringValue(action.AuthenticateOidcConfig.TokenEndpoint), + "user_info_endpoint": aws.StringValue(action.AuthenticateOidcConfig.UserInfoEndpoint), + }, + } } actions[i] = actionMap @@ -425,8 +675,10 @@ func resourceAwsLbListenerRuleUpdate(d *schema.ResourceData, meta interface{}) e for i, action := range actions { actionMap := action.(map[string]interface{}) - action := &elbv2.Action{} - action.Type = aws.String(actionMap["type"].(string)) + action := &elbv2.Action{ + Type: aws.String(actionMap["type"].(string)), + Order: aws.Int64(int64(actionMap["order"].(int))), // TODO, optional + } switch actionMap["type"].(string) { case "forward": @@ -464,6 +716,77 @@ func resourceAwsLbListenerRuleUpdate(d *schema.ResourceData, meta interface{}) e } else { return errors.New("for actions of type 'fixed-response', you must specify a 'fixed_response' block") } + + case "authenticate-cognito": + authenticateCognitoList := actionMap["authenticate_cognito"].([]interface{}) + + if len(authenticateCognitoList) == 1 { + authenticateCognitoMap := authenticateCognitoList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateCognitoMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateCognitoConfig = &elbv2.AuthenticateCognitoActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + UserPoolArn: aws.String(authenticateCognitoMap["user_pool_arn"].(string)), + UserPoolClientId: aws.String(authenticateCognitoMap["user_pool_client_id"].(string)), + UserPoolDomain: aws.String(authenticateCognitoMap["user_pool_domain"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateCognitoMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateCognitoConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateCognitoMap["scope"]; ok && scope != "" { + action.AuthenticateCognitoConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateCognitoMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateCognitoConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateCognitoMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateCognitoConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-cognito', you must specify a 'authenticate_cognito' block") + } + + case "authenticate-oidc": + authenticateOidcList := actionMap["authenticate_oidc"].([]interface{}) + + if len(authenticateOidcList) == 1 { + authenticateOidcMap := authenticateOidcList[0].(map[string]interface{}) + + authenticationRequestExtraParams := make(map[string]*string) + for key, value := range authenticateOidcMap["authentication_request_extra_params"].(map[string]interface{}) { + authenticationRequestExtraParams[key] = aws.String(value.(string)) + } + + action.AuthenticateOidcConfig = &elbv2.AuthenticateOidcActionConfig{ + AuthenticationRequestExtraParams: authenticationRequestExtraParams, + AuthorizationEndpoint: aws.String(authenticateOidcMap["authorization_endpoint"].(string)), + ClientId: aws.String(authenticateOidcMap["client_id"].(string)), + ClientSecret: aws.String(authenticateOidcMap["client_secret"].(string)), + Issuer: aws.String(authenticateOidcMap["issuer"].(string)), + TokenEndpoint: aws.String(authenticateOidcMap["token_endpoint"].(string)), + UserInfoEndpoint: aws.String(authenticateOidcMap["user_info_endpoint"].(string)), + } + + if onUnauthenticatedRequest, ok := authenticateOidcMap["on_unauthenticated_request"]; ok && onUnauthenticatedRequest != "" { + action.AuthenticateOidcConfig.OnUnauthenticatedRequest = aws.String(onUnauthenticatedRequest.(string)) + } + if scope, ok := authenticateOidcMap["scope"]; ok && scope != "" { + action.AuthenticateOidcConfig.Scope = aws.String(scope.(string)) + } + if sessionCookieName, ok := authenticateOidcMap["session_cookie_name"]; ok && sessionCookieName != "" { + action.AuthenticateOidcConfig.SessionCookieName = aws.String(sessionCookieName.(string)) + } + if sessionTimeout, ok := authenticateOidcMap["session_timeout"]; ok && sessionTimeout != 0 { + action.AuthenticateOidcConfig.SessionTimeout = aws.Int64(int64(sessionTimeout.(int))) + } + } else { + return errors.New("for actions of type 'authenticate-oidc', you must specify a 'authenticate_oidc' block") + } } params.Actions[i] = action diff --git a/aws/resource_aws_lb_listener_rule_test.go b/aws/resource_aws_lb_listener_rule_test.go index e9850740fce..2de06e8ebd2 100644 --- a/aws/resource_aws_lb_listener_rule_test.go +++ b/aws/resource_aws_lb_listener_rule_test.go @@ -341,6 +341,92 @@ func TestAccAWSLBListenerRule_priority(t *testing.T) { }) } +func TestAccAWSLBListenerRule_cognito(t *testing.T) { + var conf elbv2.Rule + lbName := fmt.Sprintf("testrule-cognito-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + targetGroupName := fmt.Sprintf("testtargetgroup-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + certificateName := fmt.Sprintf("testcert-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + cognitoPrefix := fmt.Sprintf("testcog-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_lb_listener_rule.cognito", + Providers: testAccProvidersWithTLS, + CheckDestroy: testAccCheckAWSLBListenerRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLBListenerRuleConfig_cognito(lbName, targetGroupName, certificateName, cognitoPrefix), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLBListenerRuleExists("aws_lb_listener_rule.cognito", &conf), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.cognito", "arn"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.cognito", "listener_arn"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "priority", "100"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.#", "2"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.0.type", "authenticate-cognito"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.0.order", "1"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.cognito", "action.0.authenticate_cognito.0.user_pool_arn"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.cognito", "action.0.authenticate_cognito.0.user_pool_client_id"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.cognito", "action.0.authenticate_cognito.0.user_pool_domain"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.0.authenticate_cognito.0.authentication_request_extra_params.%", "1"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.0.authenticate_cognito.0.authentication_request_extra_params.param", "test"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.0.order", "1"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.1.type", "forward"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "action.1.order", "2"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.cognito", "action.1.target_group_arn"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "condition.#", "1"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "condition.1366281676.field", "path-pattern"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.cognito", "condition.1366281676.values.#", "1"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.cognito", "condition.1366281676.values.0"), + ), + }, + }, + }) +} + +func TestAccAWSLBListenerRule_oidc(t *testing.T) { + var conf elbv2.Rule + lbName := fmt.Sprintf("testrule-oidc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + targetGroupName := fmt.Sprintf("testtargetgroup-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + certificateName := fmt.Sprintf("testcert-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_lb_listener_rule.oidc", + Providers: testAccProvidersWithTLS, + CheckDestroy: testAccCheckAWSLBListenerRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLBListenerRuleConfig_oidc(lbName, targetGroupName, certificateName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLBListenerRuleExists("aws_lb_listener_rule.oidc", &conf), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.oidc", "arn"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.oidc", "listener_arn"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "priority", "100"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.#", "2"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.type", "authenticate-oidc"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.order", "1"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.authorization_endpoint", "https://example.com/authorization_endpoint"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.client_id", "s6BhdRkqt3"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.client_secret", "7Fjfp0ZBr1KtDRbnfVdmIw"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.issuer", "https://example.com"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.token_endpoint", "https://example.com/token_endpoint"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.user_info_endpoint", "https://example.com/user_info_endpoint"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.authentication_request_extra_params.%", "1"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.authenticate_oidc.0.authentication_request_extra_params.param", "test"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.0.order", "1"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.1.type", "forward"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "action.1.order", "2"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.oidc", "action.1.target_group_arn"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "condition.#", "1"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "condition.1366281676.field", "path-pattern"), + resource.TestCheckResourceAttr("aws_lb_listener_rule.oidc", "condition.1366281676.values.#", "1"), + resource.TestCheckResourceAttrSet("aws_lb_listener_rule.oidc", "condition.1366281676.values.0"), + ), + }, + }, + }) +} + func testAccCheckAWSLbListenerRuleRecreated(t *testing.T, before, after *elbv2.Rule) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -1427,3 +1513,339 @@ resource "aws_lb_listener_rule" "50000_in_use" { } `) } + +func testAccAWSLBListenerRuleConfig_cognito(lbName string, targetGroupName string, certificateName string, cognitoPrefix string) string { + return fmt.Sprintf(`resource "aws_lb_listener_rule" "cognito" { + listener_arn = "${aws_lb_listener.front_end.arn}" + priority = 100 + + action { + order = 1 + type = "authenticate-cognito" + authenticate_cognito { + user_pool_arn = "${aws_cognito_user_pool.test.arn}" + user_pool_client_id = "${aws_cognito_user_pool_client.test.id}" + user_pool_domain = "${aws_cognito_user_pool_domain.test.domain}" + + authentication_request_extra_params { + param = "test" + } + } + } + + action { + order = 2 + type = "forward" + target_group_arn = "${aws_lb_target_group.test.arn}" + } + + condition { + field = "path-pattern" + values = ["/static/*"] + } +} + +resource "aws_iam_server_certificate" "test" { + name = "terraform-test-cert-%s" + certificate_body = "${tls_self_signed_cert.test.cert_pem}" + private_key = "${tls_private_key.test.private_key_pem}" +} + +resource "tls_private_key" "test" { + algorithm = "RSA" +} + +resource "tls_self_signed_cert" "test" { + key_algorithm = "RSA" + private_key_pem = "${tls_private_key.test.private_key_pem}" + + subject { + common_name = "example.com" + organization = "ACME Examples, Inc" + } + + validity_period_hours = 12 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] +} + +resource "aws_lb_listener" "front_end" { + load_balancer_arn = "${aws_lb.alb_test.id}" + protocol = "HTTPS" + port = "443" + ssl_policy = "ELBSecurityPolicy-2015-05" + certificate_arn = "${aws_iam_server_certificate.test.arn}" + + default_action { + target_group_arn = "${aws_lb_target_group.test.id}" + type = "forward" + } +} + +resource "aws_lb" "alb_test" { + name = "%s" + internal = true + security_groups = ["${aws_security_group.alb_test.id}"] + subnets = ["${aws_subnet.alb_test.*.id}"] + + idle_timeout = 30 + enable_deletion_protection = false + + tags { + Name = "TestAccAWSALB_cognito" + } +} + +resource "aws_lb_target_group" "test" { + name = "%s" + port = 8080 + protocol = "HTTP" + vpc_id = "${aws_vpc.alb_test.id}" + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "alb_test" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "terraform-testacc-lb-listener-rule-cognito" + } +} + +resource "aws_subnet" "alb_test" { + count = 2 + vpc_id = "${aws_vpc.alb_test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" + + tags { + Name = "tf-acc-lb-listener-rule-cognito-${count.index}" + } +} + +resource "aws_security_group" "alb_test" { + name = "allow_all_alb_test" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.alb_test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "TestAccAWSALB_cognito" + } +} + +resource "aws_cognito_user_pool" "test" { + name = "%s-pool" +} + +resource "aws_cognito_user_pool_client" "test" { + name = "%s-pool-client" + user_pool_id = "${aws_cognito_user_pool.test.id}" + generate_secret = true + allowed_oauth_flows_user_pool_client = true + allowed_oauth_flows = ["code", "implicit"] + allowed_oauth_scopes = ["phone", "email", "openid", "profile", "aws.cognito.signin.user.admin"] + callback_urls = ["https://www.example.com/callback", "https://www.example.com/redirect"] + default_redirect_uri = "https://www.example.com/redirect" + logout_urls = ["https://www.example.com/login"] +} + +resource "aws_cognito_user_pool_domain" "test" { + domain = "%s-pool-domain" + user_pool_id = "${aws_cognito_user_pool.test.id}" +}`, lbName, targetGroupName, certificateName, cognitoPrefix, cognitoPrefix, cognitoPrefix) +} + +func testAccAWSLBListenerRuleConfig_oidc(lbName string, targetGroupName string, certificateName string) string { + return fmt.Sprintf(`resource "aws_lb_listener_rule" "oidc" { + listener_arn = "${aws_lb_listener.front_end.arn}" + priority = 100 + + action { + order = 1 + type = "authenticate-oidc" + authenticate_oidc { + authorization_endpoint = "https://example.com/authorization_endpoint" + client_id = "s6BhdRkqt3" + client_secret = "7Fjfp0ZBr1KtDRbnfVdmIw" + issuer = "https://example.com" + token_endpoint = "https://example.com/token_endpoint" + user_info_endpoint = "https://example.com/user_info_endpoint" + + authentication_request_extra_params { + param = "test" + } + } + } + + action { + order = 2 + type = "forward" + target_group_arn = "${aws_lb_target_group.test.arn}" + } + + condition { + field = "path-pattern" + values = ["/static/*"] + } +} + +resource "aws_iam_server_certificate" "test" { + name = "terraform-test-cert-%s" + certificate_body = "${tls_self_signed_cert.test.cert_pem}" + private_key = "${tls_private_key.test.private_key_pem}" +} + +resource "tls_private_key" "test" { + algorithm = "RSA" +} + +resource "tls_self_signed_cert" "test" { + key_algorithm = "RSA" + private_key_pem = "${tls_private_key.test.private_key_pem}" + + subject { + common_name = "example.com" + organization = "ACME Examples, Inc" + } + + validity_period_hours = 12 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] +} + +resource "aws_lb_listener" "front_end" { + load_balancer_arn = "${aws_lb.alb_test.id}" + protocol = "HTTPS" + port = "443" + ssl_policy = "ELBSecurityPolicy-2015-05" + certificate_arn = "${aws_iam_server_certificate.test.arn}" + + default_action { + target_group_arn = "${aws_lb_target_group.test.id}" + type = "forward" + } +} + +resource "aws_lb" "alb_test" { + name = "%s" + internal = true + security_groups = ["${aws_security_group.alb_test.id}"] + subnets = ["${aws_subnet.alb_test.*.id}"] + + idle_timeout = 30 + enable_deletion_protection = false + + tags { + Name = "TestAccAWSALB_cognito" + } +} + +resource "aws_lb_target_group" "test" { + name = "%s" + port = 8080 + protocol = "HTTP" + vpc_id = "${aws_vpc.alb_test.id}" + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "alb_test" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "terraform-testacc-lb-listener-rule-cognito" + } +} + +resource "aws_subnet" "alb_test" { + count = 2 + vpc_id = "${aws_vpc.alb_test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" + + tags { + Name = "tf-acc-lb-listener-rule-cognito-${count.index}" + } +} + +resource "aws_security_group" "alb_test" { + name = "allow_all_alb_test" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.alb_test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "TestAccAWSALB_cognito" + } +}`, lbName, targetGroupName, certificateName) +} diff --git a/aws/resource_aws_lb_listener_test.go b/aws/resource_aws_lb_listener_test.go index 2e8dfe90a45..3725b5f5bdb 100644 --- a/aws/resource_aws_lb_listener_test.go +++ b/aws/resource_aws_lb_listener_test.go @@ -171,6 +171,81 @@ func TestAccAWSLBListener_fixedResponse(t *testing.T) { }) } +func TestAccAWSLBListener_cognito(t *testing.T) { + var conf elbv2.Listener + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_lb_listener.test", + Providers: testAccProvidersWithTLS, + CheckDestroy: testAccCheckAWSLBListenerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLBListenerConfig_cognito(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLBListenerExists("aws_lb_listener.test", &conf), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "load_balancer_arn"), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "arn"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "protocol", "HTTPS"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "port", "443"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.#", "2"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.type", "authenticate-cognito"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.order", "1"), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "default_action.0.authenticate_cognito.0.user_pool_arn"), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "default_action.0.authenticate_cognito.0.user_pool_client_id"), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "default_action.0.authenticate_cognito.0.user_pool_domain"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_cognito.0.authentication_request_extra_params.%", "1"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_cognito.0.authentication_request_extra_params.param", "test"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.order", "1"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.1.type", "forward"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.1.order", "2"), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "default_action.1.target_group_arn"), + ), + }, + }, + }) +} + +func TestAccAWSLBListener_oidc(t *testing.T) { + var conf elbv2.Listener + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_lb_listener.test", + Providers: testAccProvidersWithTLS, + CheckDestroy: testAccCheckAWSLBListenerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLBListenerConfig_oidc(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLBListenerExists("aws_lb_listener.test", &conf), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "load_balancer_arn"), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "arn"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "protocol", "HTTPS"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "port", "443"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.#", "2"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.type", "authenticate-oidc"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.order", "1"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.authorization_endpoint", "https://example.com/authorization_endpoint"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.client_id", "s6BhdRkqt3"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.client_secret", "7Fjfp0ZBr1KtDRbnfVdmIw"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.issuer", "https://example.com"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.token_endpoint", "https://example.com/token_endpoint"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.user_info_endpoint", "https://example.com/user_info_endpoint"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.authentication_request_extra_params.%", "1"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.authenticate_oidc.0.authentication_request_extra_params.param", "test"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.0.order", "1"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.1.type", "forward"), + resource.TestCheckResourceAttr("aws_lb_listener.test", "default_action.1.order", "2"), + resource.TestCheckResourceAttrSet("aws_lb_listener.test", "default_action.1.target_group_arn"), + ), + }, + }, + }) +} + func testAccCheckAWSLBListenerExists(n string, res *elbv2.Listener) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -724,3 +799,285 @@ resource "aws_security_group" "alb_test" { } }`, lbName) } + +func testAccAWSLBListenerConfig_cognito(rName string) string { + return fmt.Sprintf(` +resource "aws_lb" "test" { + name = "%s" + internal = false + security_groups = ["${aws_security_group.test.id}"] + subnets = ["${aws_subnet.test.*.id}"] + enable_deletion_protection = false +} + +resource "aws_lb_target_group" "test" { + name = "%s" + port = 8080 + protocol = "HTTP" + vpc_id = "${aws_vpc.test.id}" + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_internet_gateway" "test" { + vpc_id = "${aws_vpc.test.id}" +} + +resource "aws_subnet" "test" { + count = 2 + vpc_id = "${aws_vpc.test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" +} + +resource "aws_security_group" "test" { + name = "%s" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_cognito_user_pool" "test" { + name = "%s" +} + +resource "aws_cognito_user_pool_client" "test" { + name = "%s" + user_pool_id = "${aws_cognito_user_pool.test.id}" + generate_secret = true + allowed_oauth_flows_user_pool_client = true + allowed_oauth_flows = ["code", "implicit"] + allowed_oauth_scopes = ["phone", "email", "openid", "profile", "aws.cognito.signin.user.admin"] + callback_urls = ["https://www.example.com/callback", "https://www.example.com/redirect"] + default_redirect_uri = "https://www.example.com/redirect" + logout_urls = ["https://www.example.com/login"] +} + +resource "aws_cognito_user_pool_domain" "test" { + domain = "%s" + user_pool_id = "${aws_cognito_user_pool.test.id}" +} + +resource "aws_iam_server_certificate" "test" { + name = "terraform-test-cert-%s" + certificate_body = "${tls_self_signed_cert.test.cert_pem}" + private_key = "${tls_private_key.test.private_key_pem}" +} + +resource "tls_private_key" "test" { + algorithm = "RSA" +} + +resource "tls_self_signed_cert" "test" { + key_algorithm = "RSA" + private_key_pem = "${tls_private_key.test.private_key_pem}" + + subject { + common_name = "example.com" + organization = "ACME Examples, Inc" + } + + validity_period_hours = 12 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] +} + +resource "aws_lb_listener" "test" { + load_balancer_arn = "${aws_lb.test.id}" + protocol = "HTTPS" + port = "443" + ssl_policy = "ELBSecurityPolicy-2015-05" + certificate_arn = "${aws_iam_server_certificate.test.arn}" + + default_action { + order = 1 + type = "authenticate-cognito" + authenticate_cognito { + user_pool_arn = "${aws_cognito_user_pool.test.arn}" + user_pool_client_id = "${aws_cognito_user_pool_client.test.id}" + user_pool_domain = "${aws_cognito_user_pool_domain.test.domain}" + + authentication_request_extra_params { + param = "test" + } + } + } + + default_action { + order = 2 + target_group_arn = "${aws_lb_target_group.test.id}" + type = "forward" + } +} +`, rName, rName, rName, rName, rName, rName, rName) +} + +func testAccAWSLBListenerConfig_oidc(rName string) string { + return fmt.Sprintf(` +resource "aws_lb" "test" { + name = "%s" + internal = false + security_groups = ["${aws_security_group.test.id}"] + subnets = ["${aws_subnet.test.*.id}"] + enable_deletion_protection = false +} + +resource "aws_lb_target_group" "test" { + name = "%s" + port = 8080 + protocol = "HTTP" + vpc_id = "${aws_vpc.test.id}" + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_internet_gateway" "test" { + vpc_id = "${aws_vpc.test.id}" +} + +resource "aws_subnet" "test" { + count = 2 + vpc_id = "${aws_vpc.test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" +} + +resource "aws_security_group" "test" { + name = "%s" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_iam_server_certificate" "test" { + name = "terraform-test-cert-%s" + certificate_body = "${tls_self_signed_cert.test.cert_pem}" + private_key = "${tls_private_key.test.private_key_pem}" +} + +resource "tls_private_key" "test" { + algorithm = "RSA" +} + +resource "tls_self_signed_cert" "test" { + key_algorithm = "RSA" + private_key_pem = "${tls_private_key.test.private_key_pem}" + + subject { + common_name = "example.com" + organization = "ACME Examples, Inc" + } + + validity_period_hours = 12 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] +} + +resource "aws_lb_listener" "test" { + load_balancer_arn = "${aws_lb.test.id}" + protocol = "HTTPS" + port = "443" + ssl_policy = "ELBSecurityPolicy-2015-05" + certificate_arn = "${aws_iam_server_certificate.test.arn}" + + default_action { + order = 1 + type = "authenticate-oidc" + authenticate_oidc { + authorization_endpoint = "https://example.com/authorization_endpoint" + client_id = "s6BhdRkqt3" + client_secret = "7Fjfp0ZBr1KtDRbnfVdmIw" + issuer = "https://example.com" + token_endpoint = "https://example.com/token_endpoint" + user_info_endpoint = "https://example.com/user_info_endpoint" + + authentication_request_extra_params { + param = "test" + } + } + } + + default_action { + order = 2 + target_group_arn = "${aws_lb_target_group.test.id}" + type = "forward" + } +} +`, rName, rName, rName, rName) +} diff --git a/aws/structure.go b/aws/structure.go index 00856141ad9..5cd1b9c6578 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -29,6 +29,7 @@ import ( "github.com/aws/aws-sdk-go/service/elasticbeanstalk" elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice" "github.com/aws/aws-sdk-go/service/elb" + "github.com/aws/aws-sdk-go/service/elbv2" "github.com/aws/aws-sdk-go/service/iot" "github.com/aws/aws-sdk-go/service/kinesis" "github.com/aws/aws-sdk-go/service/lambda" @@ -1907,6 +1908,20 @@ func sortListBasedonTFFile(in []string, d *schema.ResourceData, listName string) return in, fmt.Errorf("Could not find list: %s", listName) } +// This function sorts LB Actions to look like whats found in the tf file +func sortActionsBasedonTypeinTFFile(actionName string, actions []*elbv2.Action, d *schema.ResourceData) []*elbv2.Action { + actionCount := d.Get(actionName + ".#").(int) + for i := 0; i < actionCount; i++ { + currAction := d.Get(actionName + "." + strconv.Itoa(i)).(map[string]interface{}) + for j, action := range actions { + if currAction["type"].(string) == aws.StringValue(action.Type) { + actions[i], actions[j] = actions[j], actions[i] + } + } + } + return actions +} + func flattenApiGatewayThrottleSettings(settings *apigateway.ThrottleSettings) []map[string]interface{} { result := make([]map[string]interface{}, 0, 1) diff --git a/website/docs/r/lb_listener.html.markdown b/website/docs/r/lb_listener.html.markdown index e10ebe3d6c2..421ee27703c 100644 --- a/website/docs/r/lb_listener.html.markdown +++ b/website/docs/r/lb_listener.html.markdown @@ -123,6 +123,36 @@ Fixed-response Blocks (for `fixed_response`) support the following: * `message_body` - (Optional) The message body. * `status_code` - (Optional) The HTTP response code. Valid values are `2XX`, `4XX`, or `5XX`. +Authenticate Cognito Blocks (for `authenticate_cognito`) supports the following: + +* `authentication_request_extra_params` - (Optional) The query parameters to include in the redirect request to the authorization endpoint. Max: 10. +* `on_unauthenticated_request` - (Optional) The behavior if the user is not authenticated. Valid values: `deny`, `allow` and `authenticate` +* `scope` - (Optional) The set of user claims to be requested from the IdP. +* `session_cookie_name` - (Optional) The name of the cookie used to maintain session information. +* `session_time_out` - (Optional) The maximum duration of the authentication session, in seconds. +* `user_pool_arn` - (Required) The ARN of the Cognito user pool. +* `user_pool_client` - (Required) The ID of the Cognito user pool client. +* `user_pool_domain` - (Required) The domain prefix or fully-qualified domain name of the Cognito user pool. + +Authenticate OIDC Blocks (for `authenticate_oidc`) supports the following: + +* `authentication_request_extra_params` - (Optional) The query parameters to include in the redirect request to the authorization endpoint. Max: 10. +* `authorization_endpoint` - (Required) The authorization endpoint of the IdP. +* `client_id` - (Required) The OAuth 2.0 client identifier. +* `client_secret` - (Required) The OAuth 2.0 client secret. +* `issuer` - (Required) The OIDC issuer identifier of the IdP. +* `on_unauthenticated_request` - (Optional) The behavior if the user is not authenticated. Valid values: `deny`, `allow` and `authenticate` +* `scope` - (Optional) The set of user claims to be requested from the IdP. +* `session_cookie_name` - (Optional) The name of the cookie used to maintain session information. +* `session_time_out` - (Optional) The maximum duration of the authentication session, in seconds. +* `token_endpoint` - (Required) The token endpoint of the IdP. +* `user_info_endpoint` - (Required) The user info endpoint of the IdP. + +Authentication Request Extra Params Blocks (for `authentication_request_extra_params`) supports the following: + +* `key` - (Required) The key of query parameter +* `value` - (Required) The value of query parameter + ## Attributes Reference The following attributes are exported in addition to the arguments listed above: diff --git a/website/docs/r/lb_listener_rule.html.markdown b/website/docs/r/lb_listener_rule.html.markdown index 7bf5a7953bb..f59f7b459cf 100644 --- a/website/docs/r/lb_listener_rule.html.markdown +++ b/website/docs/r/lb_listener_rule.html.markdown @@ -112,6 +112,8 @@ Action Blocks (for `action`) support the following: * `target_group_arn` - (Optional) The ARN of the Target Group to which to route traffic. Required if `type` is `forward`. * `redirect` - (Optional) Information for creating a redirect action. Required if `type` is `redirect`. * `fixed_response` - (Optional) Information for creating an action that returns a custom HTTP response. Required if `type` is `fixed-response`. +* `authenticate_cognito` - (Optional) Information for creating an authenticate action using Cognito. Required if `type` is `authenticate-cognito`. +* `authenticate_oidc` - (Optional) Information for creating an authenticate action using OIDC. Required if `type` is `authenticate-oidc`. Redirect Blocks (for `redirect`) support the following: @@ -130,6 +132,36 @@ Fixed-response Blocks (for `fixed_response`) support the following: * `message_body` - (Optional) The message body. * `status_code` - (Optional) The HTTP response code. Valid values are `2XX`, `4XX`, or `5XX`. +Authenticate Cognito Blocks (for `authenticate_cognito`) supports the following: + +* `authentication_request_extra_params` - (Optional) The query parameters to include in the redirect request to the authorization endpoint. Max: 10. +* `on_unauthenticated_request` - (Optional) The behavior if the user is not authenticated. Valid values: `deny`, `allow` and `authenticate` +* `scope` - (Optional) The set of user claims to be requested from the IdP. +* `session_cookie_name` - (Optional) The name of the cookie used to maintain session information. +* `session_time_out` - (Optional) The maximum duration of the authentication session, in seconds. +* `user_pool_arn` - (Required) The ARN of the Cognito user pool. +* `user_pool_client` - (Required) The ID of the Cognito user pool client. +* `user_pool_domain` - (Required) The domain prefix or fully-qualified domain name of the Cognito user pool. + +Authenticate OIDC Blocks (for `authenticate_oidc`) supports the following: + +* `authentication_request_extra_params` - (Optional) The query parameters to include in the redirect request to the authorization endpoint. Max: 10. +* `authorization_endpoint` - (Required) The authorization endpoint of the IdP. +* `client_id` - (Required) The OAuth 2.0 client identifier. +* `client_secret` - (Required) The OAuth 2.0 client secret. +* `issuer` - (Required) The OIDC issuer identifier of the IdP. +* `on_unauthenticated_request` - (Optional) The behavior if the user is not authenticated. Valid values: `deny`, `allow` and `authenticate` +* `scope` - (Optional) The set of user claims to be requested from the IdP. +* `session_cookie_name` - (Optional) The name of the cookie used to maintain session information. +* `session_time_out` - (Optional) The maximum duration of the authentication session, in seconds. +* `token_endpoint` - (Required) The token endpoint of the IdP. +* `user_info_endpoint` - (Required) The user info endpoint of the IdP. + +Authentication Request Extra Params Blocks (for `authentication_request_extra_params`) supports the following: + +* `key` - (Required) The key of query parameter +* `value` - (Required) The value of query parameter + Condition Blocks (for `condition`) support the following: * `field` - (Required) The name of the field. Must be one of `path-pattern` for path based routing or `host-header` for host based routing.