Skip to content

Commit 34b4ed3

Browse files
committed
2 parents f9a89b7 + 1a14f18 commit 34b4ed3

File tree

10 files changed

+1169
-0
lines changed

10 files changed

+1169
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Enabling East/West Communication in Multi-Account AWS Architectures with Amazon Private API Gateway.
2+
3+
![Architecture Diagram](./images/architecture.png)
4+
5+
## Architecture Overview
6+
7+
This architecture enables secure, centralized API communications across multiple AWS accounts, facilitating private east/west communication between services. The solution leverages [Amazon Private API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html), [Execute-API VPC Endpoint](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html),[VPC links](https://aws.amazon.com/blogs/compute/understanding-vpc-links-in-amazon-api-gateway-private-integrations/), and [Network Load Balancer (NLB)](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html) to establish a centralized API management model.
8+
9+
Learn more about this pattern at [Serverless Land Patterns](https://serverlessland.com/patterns/multi-account-private-apigw).
10+
11+
You can update the template to add AWS resources through the same deployment process that updates your application code.
12+
13+
Important: This application uses various AWS Services and there are costs associated with these services after the Free Tier Usage - please see the [AWS Pricing Page](https://aws.amazon.com/pricing/) for more details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
14+
15+
### Requirements
16+
17+
- Three [AWS accounts](https://signin.aws.amazon.com/signup?request_type=register). IAM users or roles with sufficient permissions to make the necessary AWS service calls and manage AWS resources.
18+
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and configured.
19+
- [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) (AWS SAM) installed.
20+
- Setup .aws/credentials [named profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) namely **centralAccount**, **accountA** and **accountB** so you can run CLI and AWS SAM commands against them.
21+
- An [Amazon VPC](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) with 1 public and 2 private subnets in each account.
22+
23+
### Deployment Instructions
24+
25+
**Note**: Please make sure to follow the below steps in order to make sure the deployment is successful.
26+
27+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
28+
``` bash
29+
git clone https://github.com/aws-samples/serverless-pattern
30+
```
31+
2. Change directory to the pattern directory:
32+
```bash
33+
cd aws-samples/serverless-patterns/multi-account-private-apigw
34+
```
35+
36+
#### VPC (Optional)
37+
1. If you do not have VPCs in your accounts, navigate to the `vpc` directory using *(if you are in a different directory, then run `cd ..` before entering the below command)*:
38+
```bash
39+
cd vpc
40+
```
41+
2. From the command line, use AWS SAM to deploy the AWS resources for the pattern as specified in the template.yaml file using **profiles** to specify the accounts:
42+
```bash
43+
sam deploy --guided --profile PROFILE_NAME
44+
```
45+
3. During the prompts:
46+
- Enter **stack name** and desired **AWS Region**.
47+
- Enter **custom CIDR Ranges** for `VpcCidr`, `PublicSubnetCidr` and `PrivateSubnet1Cidr` or use the **default CIDR ranges** by simply pressing `Enter` key.
48+
- Allow SAM CLI to create IAM roles with the required permissions.
49+
50+
Once you have run `sam deploy --guided --profile PROFILE_NAME` mode once and saved arguments to a configuration file (samconfig.toml), you can use `sam deploy --profile PROFILE_NAME` in future to use these defaults.
51+
52+
4. Note the outputs from the SAM deployment process. These contain the `VPCId`,`PublicSubnetId`,`PrivateSubnet1Id` and `PrivateSubnet2Id`. These will be used as inputs for other stack deployments.
53+
54+
#### AccountA
55+
56+
1. In account A, where you would like to create **private API Gateway** with **ECS Fargate** integration, navigate to the `accountA` directory from the main directory and deploy using *(if you are in a different directory, then run `cd ..` before entering the below command)*:
57+
```bash
58+
cd accountA
59+
60+
sam deploy --guided --profile accountA
61+
```
62+
2. During the prompts:
63+
- Enter **stack name** and desired **AWS Region**.
64+
- Enter **current account's VPC ID** where NLB and ECS Fargate will be created.
65+
- Enter **1st and 2nd Private Subnet IDs**.
66+
- Enter **Central Account's VPC ID**. This will be used in the Private API's resource policy.
67+
- Allow SAM CLI to create IAM roles with the required permissions.
68+
3. Note the outputs from the SAM deployment process. This contains the `API Gateway Invoke URL`, which will be used as inputs for central account's stack deployment.
69+
70+
#### AccountB
71+
1. In account B, where you would like to create **private API Gateway** with **Lambda** integration, navigate to the `accountB` directory from the main directory and deploy using *(if you are in a different directory, then run `cd ..` before entering the below command)*:
72+
```bash
73+
cd accountB
74+
75+
sam deploy --guided --profile accountB
76+
```
77+
2. During the prompts:
78+
- Enter **stack name** and desired **AWS Region**.
79+
- Enter **Central Account's VPC ID**. This will be used in the Private API's resource policy.
80+
- Allow SAM CLI to create IAM roles with the required permissions.
81+
3. Note the outputs from the SAM deployment process. This contains the `API Gateway's Invoke URL`, which will be used as inputs for central account's stack deployment.
82+
83+
#### Central Account
84+
1. In Central Account, where you would like to create central **private API Gateway**, navigate to the `centralAccount` directory from the main directory and deploy using (if you are in different directory, then run `cd ..` before entering the below command):
85+
```bash
86+
cd centralAccount
87+
88+
sam deploy --guided --profile CentralAccount
89+
```
90+
2. During the prompts:
91+
- Enter **stack name** and desired **AWS Region**.
92+
- Enter **Instance type** either `t2.micro` or `t2.small`
93+
- Enter **unique [Amazon Linux 2023 AMI Id](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html)** from AMI Catalog in the chosen region.
94+
- Enter **Allowed IP** from where you can SSH into the EC2 Instance. If left empty, the default CIDR range will be **0.0.0.0/0**
95+
- Enter **current account's VPC ID** where NLB and VPC Endpoint will be created.
96+
- Enter **Public Subnet ID**.
97+
- Enter **1st and 2nd Private Subnet IDs**.
98+
- Enter **Account A's Api Gateway URL**. e.g. `https://abcdefghij.execute-api.eu-west-1.amazonaws.com/Prod/`
99+
- Enter **Account B's Api Gateway URL**. e.g. `https://abcdefghij.execute-api.eu-west-1.amazonaws.com/Prod/`
100+
- Allow SAM CLI to create IAM roles with the required permissions.
101+
3. Note the outputs from the SAM deployment process. This contains `two API Gateway's Invoke URLs`, `EC2KeyPairName` to download key material and `EC2 Public IP` address.
102+
4. Follow the instructions to [store the key material from AWS System Manager parameter](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html#create-key-pair-cloudformation) into your local machine.
103+
104+
## How it works
105+
106+
This pattern utilizes three accounts and their respective templates.
107+
108+
2. **Central API Account** : Hosts the central components required to manage and route API requests securely across multiple AWS accounts. This template contains:
109+
110+
- **EC2 Instance**: Serves as an API client to initiate test requests.
111+
- **Amazon API Gateway (Private)**: A private API Gateway serves as the entry point for API requests.
112+
- **VPC Link(Private Link)**: Connects the API Gateway to an NLB within the Central Account's VPC, ensuring secure, private connectivity.
113+
- **Network Load Balancer (NLB)**: Routes incoming traffic from the VPC link to Elastic Network Interfaces (ENIs), forwarding requests to the target VPC Endpoint.
114+
- **VPC Endpoint**: The endpoint for routing/resolving incoming API requests and provides connectivity to downstream Private API Gateways in other AWS accounts (e.g., Account A and Account B).
115+
116+
3. **Account A** : Hosts a service that provides a simple HTTP response from an NGINX server running on ECS Fargate. This template contains:
117+
118+
- **Amazon API Gateway (Private)**: Receives requests from the Central API Account and forwards them as per configured paths and integration.
119+
- **VPC Link**: Connects the API Gateway to an internal NLB within Account A.
120+
- **Network Load Balancer (NLB)**: Routes traffic from the VPC link to the ECS Fargate service.
121+
- **Elastic Container Service (ECS) Fargate**: A containerized NGINX application on ECS Fargate returns a basic HTTP response. This verifies the connectivity and functionality of the architecture.
122+
123+
4. **Account B** : Hosts a Lambda function that return a simple text response to the client. This template contains:
124+
125+
- **Amazon API Gateway (Private)**: Receives requests from the Central API Account and forwards them as per configured paths and integration.
126+
- **AWS Lambda**: The Lambda function processes requests from the API Gateway and returns a simple text response to the client.
127+
128+
5. **VPC (Optional)**: Creates a VPC with CIDR Range `10.1.0.0/16` with 1 Public subnet and 2 Private subnets. This template contains:
129+
- **1 Public Subnet**: The subnet has a direct route to an [internet gateway](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html). Resources in a public subnet can access the public internet.
130+
- **2 Private subnets**: Resources in a private subnet use a [NAT gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat.html) to access the public internet.
131+
132+
## Testing
133+
1. Once you have deployed all the Stacks, [connect to your EC2 instance using SSH](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-to-linux-instance.html) or [using EC2 Instance Connect](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-linux-inst-eic.html) in **Central Account**.
134+
135+
2. After connecting to the EC2 instance, run the following `curl` command to test the **/fargate** and **/lambda** path (*replace the URL with your own API GW URL*):
136+
```bash
137+
curl --location 'https://abcdefghij.execute-api.eu-west-1.amazonaws.com/Prod/fargate'
138+
139+
curl --location 'https://abcdefghij.execute-api.eu-west-1.amazonaws.com/Prod/lambda'
140+
```
141+
142+
## Cleanup
143+
144+
To avoid incurring future charges, it's important to delete the resources in the correcct order. Follow these steps to clean up the resources created by the four templates *(Make sure to navigate to the directory containing the template before running the below commands)*:
145+
146+
1. Delete Account A template
147+
```bash
148+
sam delete --stack-name STACK_NAME --profile PROFILE_NAME
149+
```
150+
2. Delete Account B template
151+
```bash
152+
sam delete --stack-name STACK_NAME_ACCOUNT_B --profile accountB
153+
```
154+
3. Delete Central Account template
155+
```bash
156+
sam delete --stack-name STACK_NAME_CENTRAL_ACCOUNT --profile centralAccount
157+
```
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: >
4+
SAM Template for accountA containing Private API Gateway, VPC Link, Network Load Balancer, and ECS Cluster with Fargate.
5+
6+
Parameters:
7+
########### Parameters ###########
8+
VPCId:
9+
Type: AWS::EC2::VPC::Id
10+
Description: The VPC ID where the ECS service will be deployed.
11+
PrivateSubnet1:
12+
Type: AWS::EC2::Subnet::Id
13+
Description: The first private subnet ID within the VPC.
14+
PrivateSubnet2:
15+
Type: AWS::EC2::Subnet::Id
16+
Description: The second private subnet ID within the VPC.
17+
CentralAccountVpcID:
18+
Type: String
19+
Description: The ID of the VPC from the Central Account
20+
21+
Resources:
22+
########### Private API Gateway ###########
23+
PrivateApi:
24+
Type: AWS::Serverless::Api
25+
Properties:
26+
EndpointConfiguration: PRIVATE
27+
StageName: Prod
28+
AlwaysDeploy: true
29+
DefinitionBody:
30+
openapi: "3.0.1"
31+
info:
32+
title: !Sub "PrivateApi-${AWS::StackName}"
33+
version: "1.0"
34+
paths:
35+
/:
36+
get:
37+
responses:
38+
"200":
39+
description: "200 response"
40+
x-amazon-apigateway-integration:
41+
connectionId: !Ref ApiGatewayVpcLink
42+
httpMethod: GET
43+
uri: !Sub http://${NLB.DNSName}/
44+
connectionType: VPC_LINK
45+
passthroughBehavior: when_no_match
46+
type: http_proxy
47+
x-amazon-apigateway-policy:
48+
Version: "2012-10-17"
49+
Statement:
50+
- Effect: "Allow"
51+
Principal: "*"
52+
Action: "execute-api:Invoke"
53+
Resource: "execute-api:/*"
54+
Condition:
55+
StringEquals:
56+
aws:sourceVpc: !Ref CentralAccountVpcID
57+
58+
########### API Gateway VPC Link ###########
59+
ApiGatewayVpcLink:
60+
Type: AWS::ApiGateway::VpcLink
61+
Properties:
62+
Name: !Sub VPCLinkRestNlbInternal-${AWS::StackName}
63+
TargetArns:
64+
- !Ref NLB
65+
66+
########### Network Load Balancer (NLB) ###########
67+
NLB:
68+
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
69+
Properties:
70+
Name: !Sub PrivateNLB-${AWS::StackName}
71+
Scheme: internal
72+
Subnets:
73+
- Ref: PrivateSubnet1
74+
- Ref: PrivateSubnet2
75+
Type: network
76+
EnforceSecurityGroupInboundRulesOnPrivateLinkTraffic: "off"
77+
SecurityGroups:
78+
- !Ref NLBSecurityGroup
79+
80+
########### NLB Listener ###########
81+
NLBListener:
82+
Type: AWS::ElasticLoadBalancingV2::Listener
83+
Properties:
84+
DefaultActions:
85+
- Type: forward
86+
TargetGroupArn: !Ref NLBTG
87+
LoadBalancerArn: !Ref NLB
88+
Port: 80
89+
Protocol: TCP
90+
91+
########### NLB Target Group ###########
92+
NLBTG:
93+
Type: AWS::ElasticLoadBalancingV2::TargetGroup
94+
Properties:
95+
Name: !Sub FargateNLB-TG-${AWS::StackName}
96+
Port: 80
97+
Protocol: TCP
98+
VpcId: !Ref VPCId
99+
TargetType: ip
100+
HealthCheckProtocol: HTTP
101+
HealthCheckPort: '80'
102+
HealthCheckPath: '/'
103+
Matcher:
104+
HttpCode: 200
105+
106+
########### ECS Cluster ###########
107+
ECSCluster:
108+
Type: AWS::ECS::Cluster
109+
Properties:
110+
ClusterName: !Sub FargateCluster-${AWS::StackName}
111+
112+
########### ECS Fargate Task Definition ###########
113+
ECSFargateTaskDefinition:
114+
Type: AWS::ECS::TaskDefinition
115+
Properties:
116+
Family: FargateTask
117+
Cpu: 256
118+
Memory: 512
119+
NetworkMode: awsvpc
120+
RequiresCompatibilities:
121+
- FARGATE
122+
ContainerDefinitions:
123+
- Name: nginx
124+
Image: public.ecr.aws/nginx/nginx:latest
125+
Essential: true
126+
PortMappings:
127+
- ContainerPort: 80
128+
Protocol: tcp
129+
130+
########### ECS Fargate Service ###########
131+
ECSFargateService:
132+
Type: AWS::ECS::Service
133+
DependsOn: NLBListener
134+
Properties:
135+
Cluster: !Ref ECSCluster
136+
TaskDefinition: !Ref ECSFargateTaskDefinition
137+
DesiredCount: 1
138+
LaunchType: FARGATE
139+
NetworkConfiguration:
140+
AwsvpcConfiguration:
141+
AssignPublicIp: DISABLED
142+
Subnets:
143+
- Ref: PrivateSubnet1
144+
- Ref: PrivateSubnet2
145+
SecurityGroups:
146+
- !Ref ECSSecurityGroup
147+
LoadBalancers:
148+
- ContainerName: nginx
149+
ContainerPort: 80
150+
TargetGroupArn: !Ref NLBTG
151+
152+
########### ECS Security Group ###########
153+
ECSSecurityGroup:
154+
Type: AWS::EC2::SecurityGroup
155+
Properties:
156+
GroupDescription: Security group for ECS Fargate Service
157+
VpcId: !Ref VPCId
158+
SecurityGroupIngress:
159+
- IpProtocol: tcp
160+
FromPort: 80
161+
ToPort: 80
162+
SourceSecurityGroupId: !Ref NLBSecurityGroup
163+
164+
########### NLB Security Group ###########
165+
NLBSecurityGroup:
166+
Type: AWS::EC2::SecurityGroup
167+
Properties:
168+
GroupDescription: Security group for the NLB
169+
VpcId: !Ref VPCId
170+
171+
Outputs:
172+
########### Outputs ###########
173+
ApiUrl:
174+
Description: "API Gateway Invoke URL"
175+
Value: !Sub "https://${PrivateApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
176+
177+

0 commit comments

Comments
 (0)