Skip to content

Set up Private Integrations

Time Estimate: 15 - 20 minutes

AWS API gateway supports a variety of integrations including Lambda, public or private HTTP endpoints, and other AWS services such as S3 or DynamoDB.

In this module, you will integrate API Gateway with a web service running inside a private subnet of your VPC.

Important Note: For the rest of the modules, we will need the resources provisioned by CloudFormation in Module 1. To verify these resources are ready, open the CloudFormation Console and ensure that the ReinforceStack has a status of CREATE_COMPLETE.

Connect to Cloud9

  1. Go to the AWS Cloud9 console and click on Your environments (you may need to expand the left sidebar).

    What is AWS Cloud9

    AWS Cloud9 is a cloud-based integrated development environment (IDE) that lets you write, run, and debug your code with just an internet browser. It includes a code editor, debugger, and terminal. Cloud9 also provides a seamless experience for developing serverless applications enabling you to easily define resources, debug, and switch between local and remote execution of serverless applications. In this project, we are launching Cloud9 on its own EC2 instance, but you can also connect Cloud9 to an existing Linux server. For more information, see

    Cloud 9

  2. Find the reInforceCloud9 environment and click the Open IDE button as following: Open IDE

    If you have trouble opening Cloud9:

    • Ensure you are use either Chrome or Firefox browser.
    • Refer to the troubleshooting guide here to ensure third-party cookies is enabled.
  3. You should now see an integrated development environment (IDE) as shown below. You can view and edit files in the editor and run shell commands in the terminal section just like you would on a local computer.

    Keep your AWS Cloud9 IDE opened in a tab throughout this workshop as you'll use it to complete several of the remaining activities.

  4. In a separate tab, go to the EC2 console and examine the EC2 instance lab-backend. Take note of it's private IP address as shown below:

    Notice this instance is running in a private subnet and does not have a public IP address.

  5. Back in Cloud9, run the following commands in the terminal:


    You will run all terminal commands and modify all source code for these labs from within Cloud9 (not your local machine). Keep in mind that Cloud9 is a fully fledged IDE running on an Amazon EC2 instance. You can edit code and create new files via the Cloud9 editor in your browser. You can also open multiple terminals if needed.

    Pro tip

    All of the terminal commands in these modules can be copy/pasted to your terminal for execution, but keep an eye out for any highlighted sections that may need to be changed. To do this, just click the Copy to clipboard icon in the upper right corner of the greyed out section containing the commands. Then paste to your Cloud9 terminal, ensure that all of the commands finish pasting, modify any necessary parameters, and execute.

    # Install jq, a lightweight and flexible command-line JSON processor
    sudo yum install jq -y
    Note: When you execute the following, be sure to replace the IP address on the highlighted line with the privte IP of the lab-backend instance we noted above.

    curl -s|jq

    You should have some output like the following:

Create a network load balancer (NLB)

Why do we need an NLB?

To expose HTTP/HTTPS resources behind an Amazon VPC for access by clients outside of the VPC, we need to set up an API Gateway private integration. To do this, we use a VpcLink resource to encapsulate connections between API Gateway and the targeted resources. This resource relies on a network load balancer fronting our VPC resources and then targeting that network load balancer as a VpcLink from our API. For more information, see

  1. Run the following commands in Cloud9 (it might take a couple seconds to paste everything):

    # Get VPC Id. If your CloudFormaton stack or VPC name
    # is different, update it in the command
    VPC_ID=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=ReinforceStack/reInforceWorkshopVpc|jq '.Vpcs[] |  .VpcId' -r)
    # Get private subnets
    SUBNETS=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC_ID Name=tag:aws-cdk:subnet-type,Values=Private|jq '.Subnets[]|.SubnetId' -r|paste -sd' ' -)
    # Create the NLB
    NLB_ARN=$(aws elbv2 create-load-balancer --name reinforce-lab-nlb --type network --scheme internal --subnets $SUBNETS |jq '.LoadBalancers[]|.LoadBalancerArn' -r)
    # Create the target group
    TG_ARN=$(aws elbv2 create-target-group --name reinforce-targets \
     --health-check-interval-seconds 10 --healthy-threshold-count 2 --unhealthy-threshold-count 2 \
     --protocol TCP --port 80 --vpc-id $VPC_ID|jq '.TargetGroups[]|.TargetGroupArn' -r)
    # Get the instance id
    INSTANCE_ID=$(aws ec2 describe-instances --filters 'Name=tag:Name,Values=lab-backend*' --output text --query 'Reservations[*].Instances[*].InstanceId')
    # Register targets
    aws elbv2 register-targets --target-group-arn $TG_ARN --targets Id=$INSTANCE_ID
    # Create listener
    aws elbv2 create-listener --load-balancer-arn \
    $NLB_ARN --protocol TCP --port 80 \
    --default-actions Type=forward,TargetGroupArn=$TG_ARN
  2. Go to the EC2 web console. On the left side under LOAD BALANCING, click Target Groups and select reinforce-targets. Under the Targets tab, check if the registered target is healthy. If it's in the 'initial' status, wait until it becomes healthy. This may take a minute or two while the load balancer verifies the instance is ready to receive traffic.

  3. Query the NLB endpoint by running the following commands inside the same terminal:

    # Get NLB DNS
    NLB_DNS=$(aws elbv2 describe-load-balancers --load-balancer-arns $NLB_ARN|jq '.LoadBalancers[]|.DNSName' -r)
    # Invoke the GET API
    curl -s $NLB_DNS/feedback |jq

You should see similar output as when you queried the instance directly.

Go back to the API Gateway console. On the left side, click VPC Links and select Create. Enter reinforce-vpcLink as the name and select reinforce-lab-nlb as the Target NLB. Click Create.

Note: It may take a mintue or two to provision the VPC link.

  1. Click the APIs link on the left side, select Create API and create a new API named FeedbackSvc.

  2. From the Actions drop-down list, select Create Resource and create a resource with the name feedback.

  3. Select the new feedback resource and from Actions choose Create Method. Select GET from the dropdown directly underneath the resource and click the small checkmark to confirm. Enter parameters for the method as shown in the below screenshot, except do not tick the checkbox for Use Proxy Integration. For Endpoint URL, be sure to enter the DNS name of your NLB starting with http:// and ending with /feedback, for example:

    You can run the following command from your Cloud9 terminal to get this endpoint:

    echo http://$NLB_DNS/feedback

    Note: You have to wait until the VPC link created in the previous step is ready. Otherwise, you will not see it in the VPC Link dropdown list.

    Click Save to create the method and you can then use the TEST link to test it. You should once again see the same output as when you queried the instance and the NLB.

  4. Create a POST method in the same way as above by switching from GET to POST.

  5. Finally, under Actions, select Deploy API and deploy the API to a [New Stage] named prod. Once deployed, you can click the invoke URL to verify the API, for example:

Note: Don't forget to append feedback to your invoke URL or else you'll get an error.

We now have a simple sample API that allows users to submit feedback comments and view others' comments.