-
-
Notifications
You must be signed in to change notification settings - Fork 563
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add mongodb amazon vpc example
- Loading branch information
Showing
7 changed files
with
458 additions
and
0 deletions.
There are no files selected for viewing
9 changes: 9 additions & 0 deletions
9
examples/command/portals/databases/mongodb/amazon_vpc/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Amazon VPC | ||
|
||
This hands-on example uses Ockam to create an end-to-end encrypted portal to MongoDB. | ||
|
||
We connect a nodejs app in one Amazon VPC with a Amazon VPC managed Mongo database in another Amazon VPC. | ||
The example uses AWS CLI to create these VPCs. | ||
|
||
You can read a detailed walkthough of this example at: | ||
https://docs.ockam.io/portals/databases/mongodb/amazon_vpc |
51 changes: 51 additions & 0 deletions
51
examples/command/portals/databases/mongodb/amazon_vpc/analysis_corp/app.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
const { MongoClient } = require("mongodb"); | ||
|
||
// Configuration to connect to the MongoDB database on - 127.0.0.1:17017 | ||
// | ||
// 127.0.0.1:17017 is the inlet address of the tcp portal to MongoDB. | ||
// This inlet is local to analysis_corp, the MongoDB database is remote in bank_corp. | ||
const uri = "mongodb://127.0.0.1:17017/mydb" | ||
|
||
// Attempt to connect to the database in a loop. | ||
// | ||
// Since all the containers may take a few seconds to start up. | ||
// We'll attempt to connect in a loop once every 10 seconds by default. | ||
async function connect(attempts = 100, waitTimeBetweenAttempts = 10000) { | ||
while (attempts--) { | ||
const client = new MongoClient(uri); | ||
try { | ||
await client.connect(); | ||
console.log("Connected to the database.\n"); | ||
return client; | ||
} catch (err) { | ||
console.log(`Couldn't connect to the database: ${err.message}, retrying ...`); | ||
if (attempts == 0) throw err; | ||
await new Promise((resolve) => setTimeout(resolve, waitTimeBetweenAttempts)); | ||
} | ||
} | ||
} | ||
|
||
async function run() { | ||
const client = await connect(); | ||
try { | ||
const database = client.db('sample'); | ||
const users = database.collection('users'); | ||
|
||
console.log("Inserting some data into the users collections ..."); | ||
const docs = ["Alice", "Bob", "Charlie"].map((name) => ({ name: name, score: Math.floor(Math.random() * 101) })); | ||
await users.insertMany(docs); | ||
|
||
const result = await users.find().toArray() | ||
console.log("USERS:", result); | ||
console.log( | ||
"\nThe example run was successful 🥳.\n" + | ||
"\nThe app connected with the database through an encrypted portal." + | ||
"\nInserted some data, and querried it back.\n", | ||
); | ||
} finally { | ||
await client.close(); | ||
console.log("Disconnected from the database."); | ||
} | ||
|
||
} | ||
run() |
123 changes: 123 additions & 0 deletions
123
examples/command/portals/databases/mongodb/amazon_vpc/analysis_corp/run.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
#!/usr/bin/env bash | ||
set -ex | ||
|
||
run() { | ||
enrollment_ticket="$1" | ||
|
||
# ---------------------------------------------------------------------------------------------------------------- | ||
# CREATE NETWORK | ||
|
||
# Create a new VPC and tag it. | ||
vpc_id=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query 'Vpc.VpcId') | ||
aws ec2 create-tags --resources "$vpc_id" --tags "Key=Name,Value=${name}-vpc" | ||
|
||
# Create an Internet Gateway and attach it to the VPC. | ||
gw_id=$(aws ec2 create-internet-gateway --query 'InternetGateway.InternetGatewayId') | ||
aws ec2 attach-internet-gateway --vpc-id "$vpc_id" --internet-gateway-id "$gw_id" | ||
|
||
# Create a route table and a route to the Internet through the Gateway. | ||
rtb_id=$(aws ec2 create-route-table --vpc-id "$vpc_id" --query 'RouteTable.RouteTableId') | ||
aws ec2 create-route --route-table-id "$rtb_id" --destination-cidr-block 0.0.0.0/0 --gateway-id "$gw_id" | ||
|
||
# Create a subnet and associate the route table | ||
az=$(aws ec2 describe-availability-zones --query "AvailabilityZones[0].ZoneName") | ||
subnet_id=$(aws ec2 create-subnet --vpc-id "$vpc_id" --cidr-block 10.0.0.0/25 \ | ||
--availability-zone "$az" --query 'Subnet.SubnetId') | ||
aws ec2 modify-subnet-attribute --subnet-id "$subnet_id" --map-public-ip-on-launch | ||
aws ec2 associate-route-table --subnet-id "$subnet_id" --route-table-id "$rtb_id" | ||
|
||
# Create a security group to allow: | ||
# - TCP egress to the Internet | ||
# - SSH ingress from the Internet | ||
sg_id=$(aws ec2 create-security-group --group-name "${name}-sg" --vpc-id "$vpc_id" --query 'GroupId' \ | ||
--description "Allow TCP egress and Postgres ingress") | ||
aws ec2 authorize-security-group-egress --group-id "$sg_id" --cidr 0.0.0.0/0 --protocol tcp --port 0-65535 | ||
aws ec2 authorize-security-group-ingress --group-id "$sg_id" --cidr 0.0.0.0/0 --protocol tcp --port 22 | ||
|
||
# ---------------------------------------------------------------------------------------------------------------- | ||
# CREATE INSTANCE | ||
|
||
ami_id=$(aws ec2 describe-images --owners 137112412989 --query "Images | sort_by(@, &CreationDate) | [-1].ImageId" \ | ||
--filters "Name=name,Values=al2023-ami-2023*" "Name=architecture,Values=x86_64" \ | ||
"Name=virtualization-type,Values=hvm" "Name=root-device-type,Values=ebs" ) | ||
|
||
aws ec2 create-key-pair --key-name "${name}-key" --query 'KeyMaterial' > key.pem | ||
chmod 400 key.pem | ||
|
||
sed "s/\$ENROLLMENT_TICKET/${enrollment_ticket}/g" run_ockam.sh > user_data.sh | ||
instance_id=$(aws ec2 run-instances --image-id "$ami_id" --instance-type c5n.large \ | ||
--subnet-id "$subnet_id" --security-group-ids "$sg_id" \ | ||
--key-name "${name}-key" --user-data file://user_data.sh --query 'Instances[0].InstanceId') | ||
aws ec2 create-tags --resources "$instance_id" --tags "Key=Name,Value=${name}-ec2-instance" | ||
aws ec2 wait instance-running --instance-ids "$instance_id" | ||
ip=$(aws ec2 describe-instances --instance-ids "$instance_id" --query 'Reservations[0].Instances[0].PublicIpAddress') | ||
rm -f user_data.sh | ||
|
||
until scp -o StrictHostKeyChecking=no -i ./key.pem ./app.js "ec2-user@$ip:app.js"; do sleep 10; done | ||
ssh -o StrictHostKeyChecking=no -i ./key.pem "ec2-user@$ip" \ | ||
'bash -s' << 'EOS' | ||
sudo yum update -y && sudo yum install nodejs -y | ||
npm install mongodb | ||
node app.js | ||
EOS | ||
} | ||
|
||
cleanup() { | ||
# ---------------------------------------------------------------------------------------------------------------- | ||
# DELETE INSTANCE | ||
|
||
rm -f user_data.sh | ||
instance_ids=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=${name}-ec2-instance" \ | ||
--query "Reservations[*].Instances[*].InstanceId") | ||
for i in $instance_ids; do | ||
aws ec2 terminate-instances --instance-ids "$i" | ||
aws ec2 wait instance-terminated --instance-ids "$i" | ||
done | ||
|
||
if aws ec2 describe-key-pairs --key-names "${name}-key" &>/dev/null; then | ||
aws ec2 delete-key-pair --key-name "${name}-key" | ||
fi | ||
rm -f key.pem | ||
|
||
|
||
# ---------------------------------------------------------------------------------------------------------------- | ||
# DELETE NETWORK | ||
|
||
vpc_ids=$(aws ec2 describe-vpcs --query 'Vpcs[*].VpcId' --filters "Name=tag:Name,Values=${name}-vpc") | ||
|
||
for vpc_id in $vpc_ids; do | ||
internet_gateways=$(aws ec2 describe-internet-gateways --query "InternetGateways[*].InternetGatewayId" \ | ||
--filters Name=attachment.vpc-id,Values="$vpc_id") | ||
for i in $internet_gateways; do | ||
aws ec2 detach-internet-gateway --internet-gateway-id "$i" --vpc-id "$vpc_id" | ||
aws ec2 delete-internet-gateway --internet-gateway-id "$i" | ||
done | ||
|
||
subnet_ids=$(aws ec2 describe-subnets --query "Subnets[*].SubnetId" --filters Name=vpc-id,Values="$vpc_id") | ||
for i in $subnet_ids; do aws ec2 delete-subnet --subnet-id "$i"; done | ||
|
||
route_tables=$(aws ec2 describe-route-tables --filters Name=vpc-id,Values="$vpc_id" \ | ||
--query 'RouteTables[?length(Associations[?Main!=`true`]) > `0` || length(Associations) == `0`].RouteTableId') | ||
for i in $route_tables; do aws ec2 delete-route-table --route-table-id "$i" || true; done | ||
|
||
security_groups=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values="$vpc_id" \ | ||
--query "SecurityGroups[?!contains(GroupName, 'default')].[GroupId]") | ||
for i in $security_groups; do aws ec2 delete-security-group --group-id "$i"; done | ||
|
||
if aws ec2 describe-vpcs --vpc-ids "$vpc_id" &>/dev/null; then | ||
aws ec2 delete-vpc --vpc-id "$vpc_id" | ||
fi | ||
done | ||
} | ||
|
||
export AWS_PAGER=""; | ||
export AWS_DEFAULT_OUTPUT="text"; | ||
|
||
user="" | ||
command -v sha256sum &>/dev/null && user=$(aws sts get-caller-identity | sha256sum | cut -c 1-20) | ||
command -v shasum &>/dev/null && user=$(aws sts get-caller-identity | shasum -a 256 | cut -c 1-20) | ||
export name="ockam-ex-mongo-db-analysis-corp-$user" | ||
|
||
# Check if the first argument is "cleanup" | ||
# If it is, call the cleanup function. If not, call the run function. | ||
if [ "$1" = "cleanup" ]; then cleanup; else run "$1"; fi |
39 changes: 39 additions & 0 deletions
39
examples/command/portals/databases/mongodb/amazon_vpc/analysis_corp/run_ockam.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#!/bin/bash | ||
set -ex | ||
|
||
# Change into ec2-user's home directory and use sudo to run the commands as ec2-user | ||
cd /home/ec2-user | ||
sudo -u ec2-user bash << 'EOS' | ||
set -ex | ||
# Install Ockam Command | ||
curl --proto '=https' --tlsv1.2 -sSfL https://install.command.ockam.io | bash | ||
source "$HOME/.ockam/env" | ||
# Run `ockam project enroll ...` | ||
# | ||
# The `project enroll` command creates a new vault and generates a cryptographic identity with | ||
# private keys stored in that vault. | ||
# | ||
# The enrollment ticket includes routes and identifiers for the project membership authority | ||
# and the project's node that offers the relay service. | ||
# | ||
# The enrollment ticket also includes an enrollment token. The project enroll command | ||
# creates a secure channel with the project membership authority and presents this enrollment token. | ||
# The authority enrolls presented identity and returns a project membership credential. | ||
# | ||
# The command, stores this credential for later use and exits. | ||
ockam project enroll "$ENROLLMENT_TICKET" | ||
# Create an ockam node. | ||
# | ||
# Create an access control policy that only allows project members that possesses a credential with | ||
# attribute mongodb-outlet="true" to connect to TCP Portal Inlets on this node. | ||
# | ||
# Create a TCP Portal Inlet to MongoDB. | ||
# This makes the remote MongoDB available on all localhost IPs at - 0.0.0.0:17017 | ||
ockam node create | ||
ockam policy create --resource tcp-inlet --expression '(= subject.mongodb-outlet "true")' | ||
ockam tcp-inlet create --from 0.0.0.0:17017 --via mongodb | ||
EOS |
105 changes: 105 additions & 0 deletions
105
examples/command/portals/databases/mongodb/amazon_vpc/bank_corp/run.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#!/usr/bin/env bash | ||
set -ex | ||
|
||
run() { | ||
enrollment_ticket="$1" | ||
|
||
# ---------------------------------------------------------------------------------------------------------------- | ||
# CREATE NETWORK | ||
|
||
# Create a new VPC and tag it. | ||
vpc_id=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query 'Vpc.VpcId') | ||
aws ec2 create-tags --resources "$vpc_id" --tags "Key=Name,Value=${name}-vpc" | ||
|
||
# Create and Internet Gateway and attach it to the VPC. | ||
gw_id=$(aws ec2 create-internet-gateway --query 'InternetGateway.InternetGatewayId') | ||
aws ec2 attach-internet-gateway --vpc-id "$vpc_id" --internet-gateway-id "$gw_id" | ||
|
||
# Create a route table and a route to the Internet through the Gateway. | ||
rtb_id=$(aws ec2 create-route-table --vpc-id "$vpc_id" --query 'RouteTable.RouteTableId') | ||
aws ec2 create-route --route-table-id "$rtb_id" --destination-cidr-block 0.0.0.0/0 --gateway-id "$gw_id" | ||
|
||
# Create a subnet and associate the route table | ||
az=$(aws ec2 describe-availability-zones --query "AvailabilityZones[0].ZoneName") | ||
subnet_id=$(aws ec2 create-subnet --vpc-id "$vpc_id" --cidr-block 10.0.0.0/25 \ | ||
--availability-zone "$az" --query 'Subnet.SubnetId') | ||
aws ec2 modify-subnet-attribute --subnet-id "$subnet_id" --map-public-ip-on-launch | ||
aws ec2 associate-route-table --subnet-id "$subnet_id" --route-table-id "$rtb_id" | ||
|
||
# Create a security group to allow: | ||
# - TCP egress to the Internet | ||
# - No inbound connection | ||
sg_id=$(aws ec2 create-security-group --group-name "${name}-sg" --vpc-id "$vpc_id" --query 'GroupId' \ | ||
--description "Allow TCP egress and Postgres ingress") | ||
aws ec2 authorize-security-group-egress --group-id "$sg_id" --cidr 0.0.0.0/0 --protocol tcp --port 0-65535 | ||
|
||
|
||
# ---------------------------------------------------------------------------------------------------------------- | ||
# CREATE INSTANCE | ||
|
||
ami_id=$(aws ec2 describe-images --owners 137112412989 --query "Images | sort_by(@, &CreationDate) | [-1].ImageId" \ | ||
--filters "Name=name,Values=al2023-ami-2023*" "Name=architecture,Values=x86_64" \ | ||
"Name=virtualization-type,Values=hvm" "Name=root-device-type,Values=ebs" ) | ||
|
||
sed "s/\$ENROLLMENT_TICKET/${enrollment_ticket}/g" run_ockam.sh > user_data.sh | ||
instance_id=$(aws ec2 run-instances --image-id "$ami_id" --instance-type c5n.large \ | ||
--subnet-id "$subnet_id" --security-group-ids "$sg_id" \ | ||
--user-data file://user_data.sh --query 'Instances[0].InstanceId') | ||
aws ec2 create-tags --resources "$instance_id" --tags "Key=Name,Value=${name}-ec2-instance" | ||
aws ec2 wait instance-running --instance-ids "$instance_id" | ||
rm -f user_data.sh | ||
} | ||
|
||
cleanup() { | ||
# ---------------------------------------------------------------------------------------------------------------- | ||
# DELETE INSTANCE | ||
|
||
rm -f user_data.sh | ||
instance_ids=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=${name}-ec2-instance" \ | ||
--query "Reservations[*].Instances[*].InstanceId") | ||
for i in $instance_ids; do | ||
aws ec2 terminate-instances --instance-ids "$i" | ||
aws ec2 wait instance-terminated --instance-ids "$i" | ||
done | ||
|
||
# ---------------------------------------------------------------------------------------------------------------- | ||
# DELETE NETWORK | ||
|
||
vpc_ids=$(aws ec2 describe-vpcs --query 'Vpcs[*].VpcId' --filters "Name=tag:Name,Values=${name}-vpc") | ||
|
||
for vpc_id in $vpc_ids; do | ||
internet_gateways=$(aws ec2 describe-internet-gateways --query "InternetGateways[*].InternetGatewayId" \ | ||
--filters Name=attachment.vpc-id,Values="$vpc_id") | ||
for i in $internet_gateways; do | ||
aws ec2 detach-internet-gateway --internet-gateway-id "$i" --vpc-id "$vpc_id" | ||
aws ec2 delete-internet-gateway --internet-gateway-id "$i" | ||
done | ||
|
||
subnet_ids=$(aws ec2 describe-subnets --query "Subnets[*].SubnetId" --filters Name=vpc-id,Values="$vpc_id") | ||
for i in $subnet_ids; do aws ec2 delete-subnet --subnet-id "$i"; done | ||
|
||
route_tables=$(aws ec2 describe-route-tables --filters Name=vpc-id,Values="$vpc_id" \ | ||
--query 'RouteTables[?length(Associations[?Main!=`true`]) > `0` || length(Associations) == `0`].RouteTableId') | ||
for i in $route_tables; do aws ec2 delete-route-table --route-table-id "$i" || true; done | ||
|
||
security_groups=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values="$vpc_id" \ | ||
--query "SecurityGroups[?!contains(GroupName, 'default')].[GroupId]") | ||
for i in $security_groups; do aws ec2 delete-security-group --group-id "$i"; done | ||
|
||
if aws ec2 describe-vpcs --vpc-ids "$vpc_id" &>/dev/null; then | ||
aws ec2 delete-vpc --vpc-id "$vpc_id" | ||
fi | ||
done | ||
} | ||
|
||
export AWS_PAGER=""; | ||
export AWS_DEFAULT_OUTPUT="text"; | ||
|
||
user="" | ||
command -v sha256sum &>/dev/null && user=$(aws sts get-caller-identity | sha256sum | cut -c 1-20) | ||
command -v shasum &>/dev/null && user=$(aws sts get-caller-identity | shasum -a 256 | cut -c 1-20) | ||
export name="ockam-ex-mongo-db-bank-corp-$user" | ||
|
||
# Check if the first argument is "cleanup" | ||
# If it is, call the cleanup function. If not, call the run function. | ||
if [ "$1" = "cleanup" ]; then cleanup; else run "$1"; fi |
54 changes: 54 additions & 0 deletions
54
examples/command/portals/databases/mongodb/amazon_vpc/bank_corp/run_ockam.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#!/bin/bash | ||
set -ex | ||
|
||
# Change into ec2-user's home directory and use sudo to run the commands as ec2-user | ||
cd /home/ec2-user | ||
sudo -u ec2-user bash << 'EOS' | ||
set -ex | ||
# Install MongoDB https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-amazon/#install-mongodb-community-edition | ||
sudo tee /etc/yum.repos.d/mongodb-org-7.1.repo > /dev/null <<EOF | ||
[mongodb-org-7.0] | ||
name=MongoDB Repository | ||
baseurl=https://repo.mongodb.org/yum/amazon/2023/mongodb-org/7.0/x86_64/ | ||
gpgcheck=1 | ||
enabled=1 | ||
gpgkey=https://pgp.mongodb.com/server-7.0.asc | ||
EOF | ||
sudo dnf install -y mongodb-org mongodb-mongosh-shared-openssl3 openssl mongodb-org-database-tools-extra mongodb-database-tools mongodb-org-tools mongodb-org-server mongodb-org-mongos mongodb-org-database | ||
sudo systemctl restart mongod | ||
# Install Ockam Command | ||
curl --proto '=https' --tlsv1.2 -sSfL https://install.command.ockam.io | bash | ||
source "$HOME/.ockam/env" | ||
# Run `ockam project enroll ...` | ||
# | ||
# The `project enroll` command creates a new vault and generates a cryptographic identity with | ||
# private keys stored in that vault. | ||
# | ||
# The enrollment ticket includes routes and identitifiers for the project membership authority | ||
# and the project's node that offers the relay service. | ||
# | ||
# The enrollment ticket also includes an enrollment token. The project enroll command | ||
# creates a secure channel with the project membership authority and presents this enrollment token. | ||
# The authority enrolls presented identity and returns a project membership credential. | ||
# | ||
# The command, stores this credential for later use and exits. | ||
ockam project enroll "$ENROLLMENT_TICKET" | ||
# Create an ockam node. | ||
# | ||
# Create an access control policy that only allows project members that possesses a credential with | ||
# attribute mongodb-inlet="true" to connect to TCP Portal Inlets on this node. | ||
# | ||
# Create a TCP Portal Outlet to mongodb. | ||
# This makes the remote mongodb available on all localhost IPs at - 0.0.0.0:17017 | ||
ockam node create | ||
ockam relay create mongodb | ||
ockam policy create --resource tcp-outlet --expression '(= subject.mongodb-inlet "true")' | ||
ockam tcp-outlet create --to "127.0.0.1:27017" | ||
EOS |
Oops, something went wrong.