Network Prerequisites
Starting with v0.7.0, EphemeralProvider no longer creates VPC, subnet, or
security-group resources. You must provision these before instantiating the
provider and pass their IDs as required constructor arguments.
Required Resources
Parameter |
Description |
|---|---|
|
ID of an existing VPC (e.g. |
|
ID of a public subnet inside that VPC with a route to an Internet Gateway |
|
ID of a security group that allows the outbound traffic your workers need |
If any of the three is missing, the constructor raises ValueError immediately.
Minimum Security Group Rules
Workers only need outbound internet access (to reach the Parsl interchange and PyPI/package mirrors). No inbound rules are required by the provider itself.
Direction |
Protocol |
Port |
CIDR |
Purpose |
|---|---|---|---|---|
Egress |
TCP |
443 |
0.0.0.0/0 |
HTTPS (pip install, AWS API) |
Egress |
TCP |
54000–55000 |
interchange IP/32 |
Parsl ZMQ interchange |
Egress |
All |
All |
0.0.0.0/0 |
(permissive alternative) |
Minimum IAM Permissions
Do not copy a policy out of a document — this one had drifted into being unusable. Generate the current policy for the principal that runs the provider:
import json
from parsl_ephemeral_provider import EphemeralComputeProvider
print(json.dumps(EphemeralComputeProvider.minimum_iam_policy(), indent=2))
It is a @staticmethod, so no provider instance is needed, and it describes the
base EphemeralProvider just as well despite living on the Globus subclass.
Every action it grants has a call site in the package, and a unit test asserts
that in both directions.
The seven-action policy previously printed here failed at construction:
__init__ ends by calling initialize(), which resolves the AMI from SSM and
creates a launch template, so it needed ssm:GetParameter,
ec2:CreateLaunchTemplate, ec2:DescribeInstanceTypes, ec2:DescribeVpcs, and
sts:GetCallerIdentity — none of which it granted
(#195).
The workers are separate and need much less: attaching the AWS-managed
AmazonSSMManagedInstanceCore to the instance profile is the whole requirement,
which auto_create_instance_profile=True does for you.
Terraform Snippet
resource "aws_vpc" "parsl" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = { Name = "parsl-workers" }
}
resource "aws_internet_gateway" "parsl" {
vpc_id = aws_vpc.parsl.id
}
resource "aws_subnet" "parsl_public" {
vpc_id = aws_vpc.parsl.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
tags = { Name = "parsl-public" }
}
resource "aws_route_table" "parsl_public" {
vpc_id = aws_vpc.parsl.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.parsl.id
}
}
resource "aws_route_table_association" "parsl_public" {
subnet_id = aws_subnet.parsl_public.id
route_table_id = aws_route_table.parsl_public.id
}
resource "aws_security_group" "parsl_workers" {
name = "parsl-workers"
vpc_id = aws_vpc.parsl.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
output "parsl_vpc_id" { value = aws_vpc.parsl.id }
output "parsl_subnet_id" { value = aws_subnet.parsl_public.id }
output "parsl_sg_id" { value = aws_security_group.parsl_workers.id }
CloudFormation Snippet
Resources:
ParslVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
ParslIGW:
Type: AWS::EC2::InternetGateway
ParslIGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref ParslVPC
InternetGatewayId: !Ref ParslIGW
ParslSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref ParslVPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
ParslRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref ParslVPC
ParslRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref ParslRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref ParslIGW
ParslSubnetRTA:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref ParslSubnet
RouteTableId: !Ref ParslRouteTable
ParslSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Parsl worker security group
VpcId: !Ref ParslVPC
SecurityGroupEgress:
- IpProtocol: "-1"
CidrIp: 0.0.0.0/0
Outputs:
VpcId: { Value: !Ref ParslVPC }
SubnetId: { Value: !Ref ParslSubnet }
SgId: { Value: !GetAtt ParslSG.GroupId }
Using the IDs with the Provider
from parsl_ephemeral_provider import EphemeralProvider
provider = EphemeralProvider(
region="us-east-1",
instance_type="t3.small",
vpc_id="vpc-0abc1234",
subnet_id="subnet-0def5678",
security_group_id="sg-09ab0000",
auto_create_instance_profile=True,
)
For E2E tests, export the IDs as environment variables:
export AWS_TEST_VPC_ID=vpc-0abc1234
export AWS_TEST_SUBNET_ID=subnet-0def5678
export AWS_TEST_SG_ID=sg-09ab0000
AWS_PROFILE=aws pytest tests/aws/ -m aws --no-cov -v