Posted in: Technical Blogs

Building an AWS API Gateway using Pulumi

In this blog, we’ll walk you through the process of building an AWS API Gateway using Pulumi. Whether you’re transitioning from an on-premises solution or starting from scratch, this guide will help you leverage the power of AWS and Pulumi to manage your APIs efficiently.

Looking to accelerate your cloud infrastructure projects with expert guidance? Contact Tier 2 Consulting to explore how our specialised technical skills can drive your cloud computing initiatives forward.

Talk to Tier 2 for expert guidance in cloud computing

Introduction

An AWS API Gateway has been developed to address the requirements of our client, adopting a strategic move away from the on-premises server housed in the existing Data Center. Previously, the Data Center managed API calls across the network. The strategic decision involves transitioning to leverage the capabilities of the AWS cloud. The chosen solution involves implementing AWS API Gateway for executing REST API calls, utilizing the Pulumi framework.

Pulumi is an Infrastructure as Code (IaC) tool that allows users to write code in their preferred programming language to define and deploy cloud infrastructure. Through the Pulumi AWS Provider, it is possible to define and manage an API Gateway infrastructure as code. The key advantage of Pulumi lies in its compatibility with familiar languages like Python, TypeScript, JavaScript, Go, .NET, Java, and markup languages like YAML. Additionally, Pulumi offers state management, hosting the state by default, with the option to move hosting to another cloud service or manage it manually.

Prerequisites

You must have an AWS account, a Pulumi installation and the language of our choosing available prior to starting. We will use TypeScript for this example.

Overview

AWS API Gateway is an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket APIs at any scale. The important features of AWS API Gateway are as follows:

  • Support for stateful (WebSocket) and stateless (HTTP and REST) APIs.
  • Powerful, flexible authentication mechanisms, such as AWS Identity and Access Management policies, Lambda authorizer functions, and Amazon Cognito user pools.
  • Canary release deployments for safely rolling out changes.
  • CloudTrail logging and monitoring of API usage and API changes.
  • CloudWatch access logging and execution logging, including the ability to set alarms and monitoring REST API execution with Amazon CloudWatch metrics, which are very helpful when there is an issue.
  • Support for custom domain names.

We configured a POST REST API call that brings back the PDF document from a third-party provider. It then calls the back-end service, which validates and stores the document in a content management system. API Gateway handles all the tasks involved in accepting and processing up to hundreds of thousands of concurrent API calls. These tasks include traffic management, authorization and access control, monitoring, and API version management.

Steps to follow to set up AWS API Gateway using Pulumi:

1. Setting up the Pulumi project:

pulumi new aws-typescript

Note: This example uses TypeScript commands for the other languages are also available. AWS API Gateway

2. Configuring AWS API Gateway:

const api = new aws.apigateway.RestApi("my-api");
const authLambda = auth.createAuthLambda(apiName);
const authoriser = auth.createLambdaAuthoriser("my-api", apiName);
// Create an API Gateway resource
const resource = new aws.apigateway.Resource("my-resource", {
    restApi: api,
    parentId: api.rootResourceId,
    pathPart: "my-resource",
});
const method = new aws.apigateway.Method("my-method", {
    restApi: api,
    resourceId: resource.id,
    httpMethod: "ANY",
    authorization: "NONE",
    apiKeyRequired: false,
    requestParameters: {
        "method.request.querystring.myParam": true,
    },
});
// Create an integration to connect the API Gateway to the Lambda function
const integration = new aws.apigateway.Integration("my-integration", {
    restApi: api,
    resourceId: resource.id,
    httpMethod: method.httpMethod,
    integrationHttpMethod: "POST",
    type: "AWS_PROXY",
    uri: lamba.invokeArn,
});

Here’s a breakdown of the components in the example:

a. API Gateway (aws.apigateway.RestApi): This is the API Gateway service that acts as the front door for our API. It handles the HTTP requests and can route them to different resources.

b. Lambda Function (aws.lambda.Function): This is a serverless function that can be triggered by API Gateway. In this example, the Lambda function is used as an authentication service and in turn is responsible for calling the back-end service. In a real-world scenario, this Lambda function might perform some computation, access a database, or interact with other AWS services.

c. API Gateway Resource (aws.apigateway.Resource): Method (aws.apigateway.Method), and Integration (aws.apigateway.Integration): these components define how the API Gateway routes requests to the backend. The resource represents a part of our API, the method defines the HTTP method (GET, POST, etc.), and the integration links the API Gateway to the Lambda function.

3. Deploying the Infrastructure:

const config = new pulumi.Config();
const restApiId = config.require('documents-api-build-restApiID');
const deploymentVersion = config.require('documents-api-build-deploymentVersion');

const deployment = new aws.apigateway.Deployment('deployment', {
    restApi: restApiId,
    triggers: {
        version: deploymentVersion,
    }
}, {
    deleteBeforeReplace: true,
    retainOnDelete: true,
});

export const deploymentId = deployment.id;

const stage = new aws.apigateway.Stage('stage', {
    restApi: restApiId,
    deploymentId: deploymentId,
    stageName: environment,
    variables: {
        apiUrl: apiBackendDomain,
        lambdaProxyName: lambdaProxyFunctionName,
        lambdaProxyPingAuthName: pulumi.interpolate`${lambdaAuthFunctionName}:${lambdaAuthAlias.name}`,
    }
});

3.1 Deployment (aws.apigateway.Deployment): This represents a specific version of the API. Deployments allow us to manage different versions of the API and roll back changes if needed.

3.2 Stage (aws.apigateway.Stage): A stage is a named reference to a deployment, representing a specific environment (e.g., “prod” for production, stg for staging). It provides a stable endpoint for your API.

Finally export the Gateway Endpoint URL

export const apiUrl = stage.invokeUrl;

3.3 Deploying the changes:  “pulumi up” command is used to deploy and update the infrastructure. Pulumi allows us to define and manage our cloud infrastructure. The pulumi up command performs the deployment in three phases:

  • Planning: In this phase it compares the current state of your infrastructure with the desired state specified in our program and identifies the         changes that need to be made, such as creating new resources, updating existing ones or deleting unnecessary ones.
  • Preview: In this phase, it shows the preview of changes that will be applied. It gives an idea of what resources will be created, updated or           deleted.
  • Execution: After approving the above changes ‘pulumi up’ executes the deployment by communication with the cloud provider’s API to create,    update or delete the necessary resources based on the planned changes.

3.4 Stack History: Pulumi keeps a history of deployments for each stack. This allows us to track changes over time, roll back to previous versions and review the state of our infrastructure at different points.

Conclusion

By following these steps, you can effectively set up and manage your AWS API Gateway using Pulumi, leveraging the benefits of infrastructure as code and the powerful capabilities of AWS.

Need help with your cloud computing projects? Talk to us about our tailored solutions for cloud infrastructure and API management. Our team of experts is ready to assist you in achieving your digital transformation goals.

Talk to Tier 2 for expert guidance in cloud computing