Integration ExamplesΒΆ
Examples showing how to use VPC infrastructure provisioned by the VPC Provisioner with common AWS services and workflows.
Table of ContentsΒΆ
EC2 IntegrationΒΆ
Launch Instance in Private SubnetΒΆ
# Get private subnet ID from provisioned VPC
SUBNET_ID=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=edge-prod-b001-us-west-2-private-app-subnet-1" \
--query 'Subnets[0].SubnetId' --output text)
# Launch instance
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--instance-type ml.m5.xlarge \
--subnet-id $SUBNET_ID \
--security-group-ids sg-0a1b2c3d4e5f6g7h8 \
--iam-instance-profile Name=SageMakerExecutionRole \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ml-training-node}]'
Security Group for ML WorkloadsΒΆ
# Get VPC ID
VPC_ID=$(aws ec2 describe-vpcs \
--filters "Name=tag:Name,Values=edge-prod-b001-us-west-2-vpc" \
--query 'Vpcs[0].VpcId' --output text)
# Create security group for ML training
aws ec2 create-security-group \
--group-name ml-training-sg \
--description "Security group for ML training instances" \
--vpc-id $VPC_ID
# Allow internal communication within VPC
aws ec2 authorize-security-group-ingress \
--group-name ml-training-sg \
--protocol -1 \
--cidr 10.1.0.0/16
SageMaker IntegrationΒΆ
SageMaker in VPC ModeΒΆ
import sagemaker
from sagemaker.estimator import Estimator
# Use provisioned VPC subnets and security groups
estimator = Estimator(
image_uri="123456789012.dkr.ecr.us-west-2.amazonaws.com/ml-training:latest",
role="arn:aws:iam::123456789012:role/edge-prod-b001-role-sagemaker-execution",
instance_count=2,
instance_type="ml.m5.xlarge",
subnets=[
"subnet-0a1b2c3d", # private-app-subnet-1
"subnet-4e5f6g7h", # private-app-subnet-2
],
security_group_ids=["sg-0a1b2c3d4e5f6g7h8"],
output_path="s3://edge-prod-b001-us-west-2-s3/solutions/customer-churn/models/",
)
estimator.fit({
"train": "s3://edge-prod-b001-us-west-2-s3/solutions/customer-churn/data/processed/train/"
})
SageMaker Notebook in VPCΒΆ
import boto3
sagemaker_client = boto3.client('sagemaker')
sagemaker_client.create_notebook_instance(
NotebookInstanceName='ml-notebook',
InstanceType='ml.t3.medium',
RoleArn='arn:aws:iam::123456789012:role/edge-prod-b001-role-sagemaker-execution',
SubnetId='subnet-0a1b2c3d', # private-app-subnet-1
SecurityGroupIds=['sg-0a1b2c3d4e5f6g7h8'],
DirectInternetAccess='Disabled', # Access via NAT Gateway only
)
RDS IntegrationΒΆ
Database in Database SubnetΒΆ
# Get database subnet group
DB_SUBNET_1=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=edge-prod-b001-us-west-2-database-subnet-1" \
--query 'Subnets[0].SubnetId' --output text)
DB_SUBNET_2=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=edge-prod-b001-us-west-2-database-subnet-2" \
--query 'Subnets[0].SubnetId' --output text)
# Create DB subnet group
aws rds create-db-subnet-group \
--db-subnet-group-name ml-database-subnets \
--db-subnet-group-description "Database subnets for ML platform" \
--subnet-ids $DB_SUBNET_1 $DB_SUBNET_2
# Create RDS instance
aws rds create-db-instance \
--db-instance-identifier ml-metadata-db \
--db-instance-class db.t3.medium \
--engine postgres \
--master-username admin \
--master-user-password <password> \
--db-subnet-group-name ml-database-subnets \
--vpc-security-group-ids sg-database-sg \
--no-publicly-accessible
ECS/EKS IntegrationΒΆ
ECS Service in Private SubnetΒΆ
# Create ECS service using provisioned subnets
aws ecs create-service \
--cluster ml-cluster \
--service-name inference-service \
--task-definition ml-inference:1 \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={
subnets=[subnet-0a1b2c3d,subnet-4e5f6g7h],
securityGroups=[sg-0a1b2c3d4e5f6g7h8],
assignPublicIp=DISABLED
}"
EKS Cluster in VPCΒΆ
# Create EKS cluster using provisioned VPC
aws eks create-cluster \
--name ml-platform \
--role-arn arn:aws:iam::123456789012:role/eks-cluster-role \
--resources-vpc-config \
subnetIds=subnet-0a1b2c3d,subnet-4e5f6g7h,subnet-9i0j1k2l,\
securityGroupIds=sg-0a1b2c3d4e5f6g7h8
CI/CD Pipeline IntegrationΒΆ
GitHub ActionsΒΆ
name: Deploy VPC
on:
push:
branches: [main]
paths: ['vpc/configs/**']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActions
aws-region: us-west-2
- name: Validate configuration
run: |
docker run --rm \
-v ~/.aws:/home/vpcuser/.aws:ro \
-v $(pwd)/vpc/configs:/app/configs:ro \
-v $(pwd)/vpc/reports:/app/reports \
vpc-provisioner:latest \
--config edge-prod-b001-us-west-2-vpc.yaml \
--action validate-config
- name: Preview changes
run: |
docker run --rm \
-v ~/.aws:/home/vpcuser/.aws:ro \
-v $(pwd)/vpc/configs:/app/configs:ro \
-v $(pwd)/vpc/templates:/app/templates \
-v $(pwd)/vpc/reports:/app/reports \
vpc-provisioner:latest \
--config edge-prod-b001-us-west-2-vpc.yaml \
--action show-changes
- name: Deploy VPC
run: |
docker run --rm \
-v ~/.aws:/home/vpcuser/.aws:ro \
-v $(pwd)/vpc/configs:/app/configs:ro \
-v $(pwd)/vpc/templates:/app/templates \
-v $(pwd)/vpc/reports:/app/reports \
vpc-provisioner:latest \
--config edge-prod-b001-us-west-2-vpc.yaml \
--action create-vpc \
--force
Terraform IntegrationΒΆ
Reference Provisioned VPCΒΆ
# Look up VPC created by VPC Provisioner
data "aws_vpc" "provisioned" {
filter {
name = "tag:Name"
values = ["edge-prod-b001-us-west-2-vpc"]
}
}
# Look up private subnets
data "aws_subnets" "private" {
filter {
name = "vpc-id"
values = [data.aws_vpc.provisioned.id]
}
filter {
name = "tag:Name"
values = ["*private*"]
}
}
# Use in other resources
resource "aws_security_group" "app" {
vpc_id = data.aws_vpc.provisioned.id
name = "app-security-group"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [data.aws_vpc.provisioned.cidr_block]
}
}
resource "aws_lb" "app" {
name = "app-load-balancer"
internal = true
load_balancer_type = "application"
subnets = data.aws_subnets.private.ids
security_groups = [aws_security_group.app.id]
}
Cross-Provisioner IntegrationΒΆ
S3 VPC EndpointΒΆ
The S3 Provisioner can create a VPC endpoint for private S3 access using the VPC created by the VPC Provisioner:
# S3 config references VPC
s3:
vpc_id: "vpc-0a1b2c3d4e5f6g7h8"
route_table_ids: "rtb-0a1b2c3d,rtb-4e5f6g7h"
SEC Provisioner Roles in VPCΒΆ
IAM roles created by the SEC Provisioner are used by services running in the VPC:
# SageMaker execution role (from SEC) used in VPC subnets
estimator = Estimator(
role="arn:aws:iam::123456789012:role/edge-prod-b001-role-sagemaker-execution",
subnets=["subnet-0a1b2c3d", "subnet-4e5f6g7h"], # From VPC Provisioner
output_path="s3://edge-prod-b001-us-west-1-s3/...", # From S3 Provisioner
)
Discover Resources via SSMΒΆ
# Get VPC stack outputs
aws ssm get-parameters-by-path \
--path /vpc/edge-prod-b001-us-west-2-vpc/ \
--query 'Parameters[].{Name:Name,Value:Value}'
# Get SEC role ARNs
aws ssm get-parameters-by-path \
--path /security/edge-prod-b001-us-west-1-medium-sec/ \
--query 'Parameters[].{Name:Name,Value:Value}'
SDK ExamplesΒΆ
Boto3 β Discover VPC ResourcesΒΆ
import boto3
ec2 = boto3.client('ec2', region_name='us-west-2')
# Find provisioned VPC
vpcs = ec2.describe_vpcs(
Filters=[{'Name': 'tag:Name', 'Values': ['edge-prod-b001-us-west-2-vpc']}]
)
vpc_id = vpcs['Vpcs'][0]['VpcId']
# List subnets
subnets = ec2.describe_subnets(
Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}]
)
for subnet in subnets['Subnets']:
name = next((t['Value'] for t in subnet['Tags'] if t['Key'] == 'Name'), 'unnamed')
print(f"{name}: {subnet['SubnetId']} ({subnet['CidrBlock']}) - {subnet['AvailabilityZone']}")
AWS CLI β Verify DeploymentΒΆ
# Check VPC
aws ec2 describe-vpcs \
--filters "Name=tag:Name,Values=edge-prod-b001-us-west-2-vpc" \
--query 'Vpcs[0].{VpcId:VpcId,CIDR:CidrBlock,State:State}'
# Check subnets
aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=edge-prod-b001-us-west-2-*" \
--query 'Subnets[].{Name:Tags[?Key==`Name`].Value|[0],CIDR:CidrBlock,AZ:AvailabilityZone}'
# Check NAT Gateways
aws ec2 describe-nat-gateways \
--filter "Name=vpc-id,Values=vpc-0a1b2c3d4e5f6g7h8" \
--query 'NatGateways[].{Id:NatGatewayId,State:State,SubnetId:SubnetId}'