Crafting a Cohesive API on AWS Through Terraform Automation
Written on
Chapter 1: Introduction to Unified APIs
In the dynamic realm of cloud technology, the creation of a cohesive API that effortlessly connects with multiple services is an ambitious yet rewarding challenge. Our quest to enhance our infrastructure led us to devise a unified API on AWS with the help of Terraform, expertly maneuvering through the complexities of Amazon API Gateway, Amazon Route 53, and more.
Section 1.1: Setting Our Objectives
Our primary aim was to develop a unified API accessible via a custom domain, offering a straightforward and user-friendly interface. We envisioned a system where users could make requests like api.example.com/domain1, with the backend infrastructure intelligently directing the request to the correct API endpoint.
Section 1.2: The Project Landscape
Envision navigating an expansive ocean of data, where each domain serves as a distinct island brimming with information. At Sonar, our mission was to connect these islands by constructing a unified API, facilitating smooth transitions between domains. Imagine a user, positioned at the helm of api.example.com/domain1, embarking on a journey where the complexities of infrastructure are concealed, presenting a streamlined and user-centric experience.
Subsection 1.2.1: Preparing for the Journey
Before we set out on this thrilling expedition, we required a robust vessel and a dependable map. Enter Terraform, our preferred tool for shaping the AWS environment. By utilizing Terraform, we could define our infrastructure as code, ensuring a reproducible and scalable approach.
# main.tf
provider "aws" {
region = "us-east-1" # Modify to your preferred region
}
# Define AWS resources: VPC, subnets, security groups, etc.
# Creating a VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "MainVPC"}
}
# Creating public and private subnets
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = "us-east-1a" # Adjust the availability zone as necessary
map_public_ip_on_launch = true
tags = {
Name = "PublicSubnet-${count.index + 1}"}
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 3}.0/24"
availability_zone = "us-east-1a" # Adjust the availability zone as necessary
tags = {
Name = "PrivateSubnet-${count.index + 1}"}
}
# Creating a security group for the VPC
resource "aws_security_group" "vpc_sg" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
This Terraform configuration establishes a basic VPC with public and private subnets across two availability zones in the specified region. Additionally, a security group is created to permit incoming traffic on port 80 and allow all outgoing traffic. Adjust these settings based on your specific needs and security considerations.
Section 1.4: The Guiding Light of Amazon API Gateway
As we ventured deeper into our journey, Amazon API Gateway revealed itself as our beacon. Its vital features, including private REST APIs and custom domains, became the guiding compass of our expedition.
# api_gateway.tf
resource "aws_api_gateway_rest_api" "private_api" {
name = "private-api"
description = "Private API for Sonar"
endpoint_configuration {
types = ["PRIVATE"]}
}
# Defining a resource
resource "aws_api_gateway_resource" "api_resource" {
rest_api_id = aws_api_gateway_rest_api.private_api.id
parent_id = aws_api_gateway_rest_api.private_api.root_resource_id
path_part = "domain1"
}
# Defining a method for the resource
resource "aws_api_gateway_method" "api_method" {
rest_api_id = aws_api_gateway_rest_api.private_api.id
resource_id = aws_api_gateway_resource.api_resource.id
http_method = "ANY"
authorization = "NONE"
}
# Defining an integration to connect the method with your backend
resource "aws_api_gateway_integration" "api_integration" {
rest_api_id = aws_api_gateway_rest_api.private_api.id
resource_id = aws_api_gateway_resource.api_resource.id
http_method = aws_api_gateway_method.api_method.http_method
type = "HTTP_PROXY"
integration_http_method = "ANY"
}
# Defining a method response
resource "aws_api_gateway_method_response" "api_method_response" {
rest_api_id = aws_api_gateway_rest_api.private_api.id
resource_id = aws_api_gateway_resource.api_resource.id
http_method = aws_api_gateway_method.api_method.http_method
status_code = "200"
}
In this segment, we configure an API resource for "domain1," an HTTP method (ANY), an integration for backend connectivity, and a method response. Make sure to replace placeholder values with your actual backend API endpoint.
With each Terraform command, we meticulously crafted our unified API, laying the groundwork for an effortless user experience.
Section 1.5: Harmonizing Private APIs with Custom Domains
To achieve the seamless union of private APIs with custom domains, we interlinked components using interface VPC endpoints (ENIs) and a clever workaround documented in the AWS samples repository.
# vpc_endpoint.tf
resource "aws_vpc_endpoint" "api_gateway_endpoint" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.region}.execute-api"
vpc_endpoint_type = "Interface"
}
# custom_domain.tf
resource "aws_api_gateway_domain_name" "custom_domain" {
domain_name = "api.example.com"
certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/abc12345-defg-6789-hijk-lmnopqrstuvwx"
security_policy = "TLS_1_2"
endpoint_configuration {
types = ["PRIVATE"]
vpc_endpoint_ids = [aws_vpc_endpoint.api_gateway_endpoint.id]
}
}
In this configuration, we create an interface VPC endpoint for the API Gateway service, ensuring secure communication without traversing the public internet. Additionally, we define a custom domain for "api.example.com," including settings for the SSL certificate and endpoint configuration.
As we finalized our setup, our unified API stood ready to welcome users into a realm where complexity is replaced by simplicity.
Chapter 2: Conclusion and Reflection
With our infrastructure established, interconnected, and operational, we achieved a unified API accessible via a custom domain. Users can now seamlessly make requests to api.example.com/domain1, with our system adeptly routing these requests through Amazon Route 53, ALB, and the sophisticated Amazon API Gateway.
Our expedition through the data seas has ushered in a new era of infrastructure management. By harnessing Terraform and AWS services, we not only accomplished our goal of a unified API but also built a scalable and maintainable infrastructure.
In Conclusion: Embrace Your Cloud Journey
Creating a unified API on AWS is a fulfilling venture. With the right tools and mindset, any team can navigate the intricacies and emerge victorious in the cloud. Our journey into cloud architecture has imparted invaluable insights and established a solid foundation for future growth.
As you embark on your cloud adventure, may your APIs be cohesive, your infrastructure adaptable, and your journey as thrilling as ours. Happy coding!
The first video showcases how to automate AWS cloud management using Terraform, providing insights into best practices and implementation strategies.
The second video discusses the integration and security of Terraform Cloud, Vault, GitHub, and AWS, focusing on enhancing your cloud infrastructure.