Question: How can I use a Lambda-backed API as the custom identity provider for my Transfer Family server without using CloudFormation?

I want to use an AWS Lambda-backed Amazon API Gateway API as the custom identity provider for my AWS Transfer Family server. However, I don't want to use one of the AWS CloudFormation stack templates for my configuration. Or, I want to customize my configuration. How can I set up a custom identity provider this way?Short descriptionYou can choose to manually configure a Lambda-backed API Gateway API as the custom identity provider for your Transfer Family server, instead of using one of the CloudFormation stack templates. To do this, you can directly configure a Lambda function and an API Gateway API with your server.For example, to set up the same configuration as the basic stack template, follow these steps:1.    Create an AWS Identity and Access Management (IAM) role for the Lambda execution role.2.    Create the Lambda function.3.    (Optional) Create an IAM role for the API Gateway logging role.4.    Set up an API Gateway API as the identity provider.5.    Create IAM roles for the Transfer Family server and server users.6.    Create the Transfer Family server.7.    Set up your credential store.

ResolutionImportant: This configuration is one example of how to set up your custom identity provider without using a CloudFormation stack template. You must modify the configuration steps based on your specific needs for the custom identity provider.Create an IAM role for the Lambda execution role1.    Use the IAM console to create the execution role. Note: For this configuration, you need only the basic execution permissions. However, be sure to customize the permissions for your use case.2.    Modify the role's trust policy to add the following statement:{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "Service": "lambda.amazonaws.com"      },      "Action": "sts:AssumeRole"    }  ]}Create the Lambda functionFollow the steps to create a Lambda function using the console. Be sure to configure the following:1.    For the Execution role, select the Lambda execution role that you created.2.    For the Function code, you can use the default Lambda function for authentication. Or, you can use a custom function.(Optional) Create an IAM role for the API Gateway logging roleYou can use Amazon CloudWatch Logs to help you debug errors with your REST API. To create a logging role, follow these steps:1.    Create an IAM role for API Gateway and attach the AmazonAPIGatewayPushToCloudWatchLogs managed policy to the role.2.    Modify the role's trust policy to add the following statement:{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "Service": "apigateway.amazonaws.com"      },      "Action": "sts:AssumeRole"    }  ]}Set up an API Gateway API as the identity provider1.    Open the API Gateway console.2.    From the navigation pane, choose APIs.3.    Choose Create API.4.    For Choose an API type, navigate to REST API, and then choose Build. Then, enter the following: For Choose the protocol, select REST. For Create new API, select New API. For API name, enter a name for your API. For Endpoint Type, select Regional.Note: Don't build your API from the REST API Private option.5.    Choose Create API.6.    From the navigation pane, choose Models. Then, choose Create.7.    For Model name, enter UserConfigResponseModel.8.    For Content type, enter application/json.9.    For Model schema, enter the following:{"$schema":"http://json-schema.org/draft-04/schema#","title":"UserUserConfig","type":"object","properties":{"Role":{"type":"string"},"Policy":{"type":"string"},"HomeDirectory":{"type":"string"},"PublicKeys":{"type":"array","items":{"type":"string"}}}}10.    ChooseCreate model.11.    From the navigation pane, choose Resources.12.    Expand Actions, and then choose Create Resource.13.    Create a resource for your Transfer Family servers. For Resource Name, enter Servers. For Resource Path, enter servers.14.    Create a resource for the server ID. For Resource Name, enter ServerID. For Resource Path, enter {serverId}.15.    Create a resource for your server users. For Resource Name, enter Users. For Resource Path, enter users.16.    Create a resource for the user names. For Resource Name, enter Username. For Resource Path, enter {username}.17.    Create a resource for user configurations. For Resource Name, enter GetUserConfig. For Resource Path, enter config.18.    Expand Actions, and then choose Create Method.19.    From the dropdown list, select GET. Then, choose the check icon next to GET to create the method.20.    For GET - Setup, enter the following: For Integration type, select Lambda Function. For Lambda Region, select the AWS Region that your Lambda function is in. For Lambda Function, select the function that you created.21.    Choose Save.22.    Choose Method Request. Then, enter the following: For Authorization, select AWS_IAM. For HTTP Request Headers, choose Add header. Then, enter Password as a header name. For URL Query String Parameters, choose Add query string. Then, enter protocol as a query string name. Choose Add query string again, and then enter sourceIp as another query string name.23.    From the navigation bar of the GET method, choose Method Execution to return to the GET - Method Execution page.24.    Choose Integration Request. Then, expand Mapping Templates.25.    For Request body passthrough, select When no template matches the request Content-Type header.26.    For Content-Type, enter application/json. Choose the check icon to confirm.27.    For the template, enter the following:{ "username": "$input.params('username')", "password": "$util.escapeJavaScript($input.params('Password')).replaceAll("\\'","'")", "serverId": "$input.params('serverId')", "protocol": "$input.params('protocol')","sourceIp": "$input.params('sourceIp')" }28.    ChooseSave.29.    From the navigation bar of the GET method, choose Method Execution to return to the GET - Method Execution page.30.    Choose Integration Response. Confirm that there are no mapping templates and that the response body is passed through to the method response.31.    From the navigation bar of the GET method, choose Method Execution to return to the GET - Method Execution page.32.    Choose Method Response. Then, expand 200.33.    For Response Body for 200, edit the Models value, and then select the UserConfigResponseModel that you created in steps 7 through 10. Choose the check icon to confirm.34.    From the Resources navigation pane, choose GET, choose Actions, and then choose Deploy API. Enter the following: For Deployment stage, select [New Stage]. For Stage name, enter a name for the stage.35.    Choose Deploy.36.    From the navigation pane, choose Stages. Then, choose Create and enter the following: For Stage name, enter prod. For Deployment, select the deployment that you created as a new stage.37.    Choose Create.Create IAM roles for the Transfer Family server and server users1.    Create an IAM role for the Transfer Family server that grants permissions to invoke the API that you created, similar to the following:{  "Version": "2012-10-17",  "Statement": [      {          "Action": [              "execute-api:Invoke"          ],          "Resource": "arn:aws:execute-api:{Region}:{AWS-Account-ID}:{API-Gateway-id}/{stage}/GET/*",          "Effect": "Allow"      },      {          "Action": [              "apigateway:GET"          ],          "Resource": "*",          "Effect": "Allow"      }  ]}2.    Modify the role's trust policy to add the following statement:{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "Service": "transfer.amazonaws.com"      },      "Action": "sts:AssumeRole"    }  ]}3.     Create an IAM role for the Transfer Family server users that grants access to the Amazon Simple Storage Service (Amazon S3) bucket. Then, modify the role's trust policyto add the statement from step 2.4.    Create an IAM role for the Transfer Family server that sends logs to CloudWatch. Then, modify the role's trust policy to add the statement from step 2.Create the Transfer Family serverFollow the steps to create a Transfer Family server. Be sure to configure the following:1.    For Identity provider type, select Custom. Then, for Custom provider, enter the API that you created.2.    For Invocation role, select the IAM role that grants the server permissions to invoke the API that you created.3.    For Logging role, select the IAM role for the server that sends logs to CloudWatch.Set up your credential storeYou must set up your credential store for the user configuration. For more information on setting up a credential store, see Default Lambda function and Enable password authentication for AWS Transfer for SFTP using AWS Secrets Manager.At minimum, you must set up the following fields for users to be able to perform actions on the Amazon S3 bucket:User namePasswordHomeDirectoryRoleNote: The role is the Amazon Resource Name (ARN) of the IAM role that you created to grant server users access to the Amazon S3 bucket.Testing and troubleshooting your setupYou can test your setup in the following ways:Use the API Gateway console to test.Use the Transfer Family console or the AWS Command Line Interface (AWS CLI) to test the identity provider.Try logging in to the Transfer Family server from a client.If you run into issues with your setup, you can troubleshoot in the following ways:Check the response from the test identity provider. If the status code isn't 200, then there might be issues with the API setup.Confirm that the IAM roles that you created have the correct permissions and trust relationships.This configuration turns on logging, and you can review Lambda execution logs, API Gateway logs, and Transfer Family logs to identify issues.If the custom identity provider setup that you need matches one of the available CloudFormation stacks, then you can try deploying the CloudFormation template and compare with your setup to identify issues.