emr-spark-8.0.0 — see Version compatibility for what changes.
For existing Apache Sedona users
If you already run Apache Sedona on Amazon EMR, moving to WherobotsDB takes two changes:-
Replace the JAR. Swap the public Apache Sedona JAR from Maven Central for the WherobotsDB EMR JAR that Wherobots supplies.
The WherobotsDB build adds the enterprise functions, Wherobots Cloud authentication, and the metering client.
- Add your Wherobots API key. See Give Secret Manager Access and Create cluster.
Before you start
The following requirements must be met within both your Wherobots Organization and AWS account before you begin:Wherobots Requirements
Wherobots Requirements
- An Admin account within a Professional, Innovation, or Enterprise Edition Organization.
Wherobots Organization members with the User role can use a cluster an Admin has already set up, but cannot create the API key this deployment requires. See Organization Roles.
- Community Edition is not supported. See Organization Editions or Upgrade Organization.
- The BYOS feature enabled on your Organization. Contact Wherobots to enable it. BYOS unlocks both halves of this deployment: read access to the WherobotsDB release JARs, and the runtime authentication and usage-reporting endpoints the JAR calls. Without it, those endpoints return
403and cluster initialization fails. - A Wherobots API key. You create this in Give Secret Manager Access.
AWS Requirements
AWS Requirements
- An AWS account.
- Permission to create IAM roles, instance profiles, and inline policies in that account. This guide creates three roles — an EMR service role, an EC2 instance role, and an EMR Studio service role — plus one instance profile.
AdministratorAccessis sufficient but broader than required. For the specific actions involved, see Actions defined by AWS Identity and Access Management and Actions, resources, and condition keys for Amazon EMR in the AWS documentation. - Permission to create an S3 bucket, an EMR cluster, EC2 security groups, an EMR Studio, and a Secrets Manager secret.
iam:PassRoleon the three roles this guide creates.create-clusterpasses both the service role and the instance profile, andcreate-studiopasses the Studio service role, so an identity withoutiam:PassRoleonWherobotsEMRServiceRole,WherobotsEMRInstanceRole, andWherobotsEMRStudioServiceRolereceivesAccessDeniedbefore either resource is created. This is a permission on the operator running these commands, distinct from theiam:PassRolethe service role itself is granted in Create Service Role.- An Amazon EMR 7.x or later release. This guide targets
emr-7.8.0. EMR 6.x is not supported — see Version compatibility. - A VPC and subnet for the cluster. The EMR Studio you create later must use the same subnet as the cluster.
- Outbound HTTPS (port 443) from the cluster to Wherobots Cloud, for license metering. A cluster in a private subnet needs a NAT gateway or an equivalent egress path; without it,
SedonaContext.createfails to authenticate. - The WherobotsDB release bundle from Wherobots, containing the shaded JARs, the
geotools-wrapperJAR, and thewherobots-sedonaPython wheels. These are not published to Maven Central or PyPI.
Version compatibility
WherobotsDB JARs are compiled against JDK 17, so Amazon EMR 7.x or later is required. Choose the JAR that matches your EMR release:NoSuchMethodError or ClassNotFoundException.
Every command in this guide targets emr-7.8.0. To deploy on emr-spark-8.0.0 instead, make all four substitutions below. They must move together — a release label that disagrees with the JAR produces the NoSuchMethodError described above.
VERSION and GEOTOOLS_VERSION are different values. For example:
Install WherobotsDB on an EMR cluster
Installing WherobotsDB involves staging its artifacts in Amazon S3, granting your cluster access to them, and launching an EMR cluster that loads them at startup. Complete the sections in the order listed below; later sections depend on values produced by earlier ones.Prepare your command line
Allaws commands in this guide are run from a terminal on your local machine, not on the cluster.
To prepare your environment, complete the following steps:
Install the AWS CLI
Confirm your credentials
ExpiredToken or Unable to locate credentials, re-authenticate with aws sso login or aws configure before continuing.Set a default region
--region, so your profile must have one set. Confirm it:create-cluster, the EC2 lookups, and the S3 calls:Collect the required values
cat > filename <<'EOF' … EOF to create a file in the current working directory. Run every command in this guide from that same directory.
file://, for example --policy-document file://ec2-trust.json. The prefix instructs the AWS CLI to read the argument from a file rather than interpret it as a literal value, and it is required. Omitting it causes the command to fail, because the CLI treats the filename itself as the policy document.The path after file:// is relative to your current directory. If you keep these files elsewhere, supply the full path instead, for example file:///Users/name/emr-setup/ec2-trust.json.File destinations
This guide works with two kinds of files: the artifacts Wherobots supplies, and the files you author yourself. Five objects are uploaded to Amazon S3 and read by the cluster at runtime. The remaining files you author are never uploaded — the AWS CLI reads them from disk and submits their contents to Amazon EMR and IAM, which retain them as part of the cluster definition and the roles’ policies.Configure your S3 bucket
In AWS, create a bucket with the following subdirectories:- AWS S3 Console
- AWS CLI
Create the S3 bucket
- In the AWS Console navigate to S3 → Create bucket. Enter
YOUR_BUCKET_NAME, choose the region, enable default encryption and versioning as required, then click Create bucket.
Create the folders (prefixes)
- Open the bucket in the Console, click Create folder, and add the following folders:
apps,emr-logs,studio, andwherobots. Insidewherobots, createbootstrap,jars, andwheels.
wherobots prefix contains exactly three folders: bootstrap/, jars/, and wheels/.wherobots/jars/ prefix:
Configuration JSON
This file defines the Spark properties that load the WherobotsDB JARs and register the spatial SQL functions. It is not uploaded to Amazon S3. Instead,create-cluster reads it from your local disk and submits its contents to Amazon EMR, which retains them as part of the cluster definition.
To create the configuration file, complete the following steps:
Create the file on your local machine
configurations.json using a text editor, and paste in the following:Replace the JAR filenames
VERSION and GEOTOOLS_VERSION in both spark.jars and spark.yarn.dist.jars with the versions of the JARs you uploaded to wherobots/jars/. The two properties must list the same two JARs, in the same order.Validate the JSON
create-cluster to fail immediately with a parse error.aws emr describe-cluster --cluster-id CLUSTER_ID --query 'Cluster.Configurations'.Bootstrap script
A bootstrap action is a script that Amazon EMR runs on every node of the cluster during creation, before Spark is installed. This script copies the WherobotsDB JARs from Amazon S3 onto each node and installs thewherobots-sedona Python client.
The API key is not handled here. Bootstrap actions run before Spark exists, and a shell export in a bootstrap script exits before any Spark process starts, so the variable never reaches them. The key is supplied by a cluster step instead — see Create cluster.
You do not run this script yourself. You create it on your local machine, upload it to Amazon S3, and reference its S3 path in the --bootstrap-actions argument of Create cluster. Amazon EMR retrieves and runs it on each node.
To create and upload the bootstrap script, complete the following steps:
Create the file on your local machine
bootstrap-wherobotsdb.sh using a text editor, and paste in the script below.Edit the configuration block
Configuration: edit this section block at the top of the file. Leave the rest of the script unchanged.sudo "${PY_BIN}" -m pip rather than hard-coding an interpreter. On EMR 7.8.0 PY_BIN and python3 are the same binary, but on emr-spark-8.0.0 they are not — using ${PY_BIN} keeps the script correct on both.Upload the script to Amazon S3
Verify the upload
WHL file
Thewherobots-sedona Python client is distributed as prebuilt wheels in the WherobotsDB release bundle, alongside the JARs. It is not published to PyPI.
You still install it with pip — you just point pip at the wheel file rather than at a package name. pip install wherobots-sedona cannot resolve, because there is no index to resolve it from; pip install /path/to/wherobots_sedona-....whl works normally, which is what the bootstrap script does.
The wheel filename encodes both a Python version tag and a CPU architecture, and both must match your cluster.
Pick the Python tag from your EMR release:
macosx_* and win_* wheels. Those are for local development — cluster nodes always take a manylinux wheel.
To upload the wheel, complete the following steps:
Confirm your cluster's Python tag and architecture
emr-7.8.0 on r8g.xlarge, which is Graviton, so they use the cp39 / aarch64 wheel.Create the wheels prefix
Upload the wheel
Verify the upload
SEDONA_WHEEL in the bootstrap script exactly.Create IAM roles
This deployment uses three IAM roles. Confusing the first two is the most common setup mistake:aws iam commands read them from disk and submit their contents to IAM, which stores them on the role:
Create Service Role
To create the role Amazon EMR uses to manage your cluster, complete the following steps in your terminal:Create the role
Attach the AWS managed policy
AmazonEMRServicePolicy_v2 alone is not sufficient for this setup. It scopes its EC2 permissions to resources carrying the for-use-with-amazon-emr-managed-policies tag, and it does not grant iam:PassRole for a custom instance profile name such as WherobotsEMRInstanceRole. The inline policy you add in the next two steps supplies both: explicit access to your subnet and security groups, and iam:PassRole for the instance profile.Look up your security group IDs
SECURITY_GROUP_ID_MASTER and SECURITY_GROUP_ID_SLAVE.- In the policy file in the next step, remove the two
security-groupARNs from theCreateInNetworkstatement, keeping its subnet ARN, and delete the entireManageSecurityGroupsstatement. ItsResourcearray contains only those two ARNs, so removing them individually would leave an empty array, whichput-role-policyrejects as invalid. - In Create cluster, omit
EmrManagedMasterSecurityGroup=andEmrManagedSlaveSecurityGroup=from--ec2-attributes. Amazon EMR then creates its default managed groups during launch. TheCreateDefaultSecurityGroupInVPCstatement is what permits this. - Afterwards, re-run the lookup above, add the two ARNs back to
CreateInNetwork, restore theManageSecurityGroupsstatement, and re-apply the policy withput-role-policy.
Create the policy file
SUBNET_ID, SECURITY_GROUP_ID_MASTER, SECURITY_GROUP_ID_SLAVE, VPC_ID, and ACCOUNT_ID, then run:Verify both policies are attached
AmazonEMRServicePolicy_v2. The second must list wherobots-emr-network-access.Give Secret Manager Access
To store your Wherobots API key in AWS Secrets Manager and grant the cluster access to it, complete the following steps:Create a Wherobots API key
Store the key as a secret
0600 file instead, hand that file to the CLI, then delete it:read -rs keeps the key off the screen, printf '%s' writes it without a trailing newline, and umask 077 makes the file readable only by you.Store the key as plaintext — no JSON wrapper and no trailing newline. The key step reads the value verbatim, so anything extra ends up inside the key.Note the secret's ARN
...:secret:wherobots/api-key-Ab3xY9.Create the access policy file
YOUR_BUCKET_NAME, REGION_IDENTIFIER, and ACCOUNT_ID, then run:Create Instance Profile
An instance profile is a wrapper that lets EC2 machines use an IAM role. The role by itself is not enough — EC2 can only assume a role that is wrapped in an instance profile of the same name. To create it, complete the following steps in your terminal:Create the role
Attach the access policy
Wrap the role in an instance profile
Verify the grants
WherobotsEMRInstanceRole under Roles. If it returns an empty list, the previous step did not complete.Create security groups
EMR Studio reaches the cluster over port18888, the Jupyter Enterprise Gateway. That requires two security groups: an engine group attached to the cluster’s primary node, and a workspace group attached to the Workspace.
In your terminal, create both groups and connect them:
ENGINE_SECURITY_GROUP_ID, and Create EMR Studio uses both.
ec2:RunInstances on it — which AmazonEMRServicePolicy_v2 grants only for tagged security groups. The alternative is to add its ARN to the CreateInNetwork statement of the service role policy.$ENG and $WS are shell variables that exist only in the terminal session that created them. If you open a new terminal before finishing this guide, re-read the IDs with aws ec2 describe-security-groups --filters Name=group-name,Values=emr-studio-engine-sg,emr-studio-workspace-sg --query 'SecurityGroups[].{Name:GroupName,Id:GroupId}' --output table.Create cluster
The following steps create an EMR cluster that runs WherobotsDB. You can also use an existing EMR cluster, but it must meet the requirements outlined in the Before you start section, and it must already carry the engine security group on its primary node. The API key reaches Spark through a step that runs immediately after the cluster starts. It reads the secret on the primary node and writesspark.wherobots.api.key into Spark’s own configuration file, so every later session picks it up. This cannot be done in the bootstrap script, because Spark is not installed yet when bootstrap actions run.
In your terminal, save the following as configure_key.py:
apps/ prefix, where the cluster’s first step reads it from:
spark.redaction.regex is set in Configuration JSON rather than here, because it is not a secret and should apply from the moment the cluster starts. Spark’s default value, (?i)secret|password|token, does not match spark.wherobots.api.key; without extending it the key appears in the Spark UI Environment tab and in the event logs written to S3.Run create-cluster
ENGINE_SECURITY_GROUP_ID with the engine group ID from Create security groups. This is what lets EMR Studio reach the cluster, and it cannot be added after launch.The command returns a ClusterId. Use it as CLUSTER_ID in the steps that follow.Wait for the cluster to be ready
STARTING, BOOTSTRAPPING, and RUNNING before reaching WAITING, which takes roughly five to ten minutes.Confirm the bootstrap installed the Python client
EMR Studio Notebook
EMR Studio is the browser-based notebook environment for EMR. A Studio is the container; a Workspace is an individual notebook environment inside it that attaches to a cluster.Create EMR Studio
A Studio needs its own service role, which EMR Studio uses to store notebook files in your bucket and to attach Workspaces to clusters. To create the Studio, complete the following steps in your terminal:Create the Studio service role
studio-trust.json trust policy you created in Create IAM roles:Create and attach the Studio policy
YOUR_BUCKET_NAME, then run:Create the Studio
StudioId and a Url. Save the URL — it is how you open the Studio.Launch notebook and attach cluster
Creating a Workspace has no CLI equivalent. To create one, complete the following steps in the AWS Console:Open the Studio
Url returned by create-studio, or in the AWS Console navigate to EMR → EMR Studio, then select your Studio.Create a Workspace
Attach the cluster
Launch and choose a kernel
Ready status has its cluster and security group fields locked. Stop the Workspace first if you need to change which cluster it attaches to, then start it again.Test in EMR Studio Notebook
These commands run in a notebook in your browser, not in your terminal. Nothing is installed in the notebook session and no API key is entered, because the bootstrap action and theconfigure-wherobots-key step have already supplied both.
To open the notebook, complete the following steps:
Open EMR Studio
Url returned by aws emr create-studio.To retrieve the URL again, run:Open your Workspace
Ready. If it is Stopped, select Start and wait for it to become Ready.Confirm the cluster is attached
Create a PySpark notebook
Confirm the client is installed against the interpreter Spark uses
No module named 'sedona', the wheel did not install. Check the bootstrap log for WARN: 'sedona' is NOT importable.Initialize Sedona
Run the validation query
spark.sql.extensions is set, ST_* functions are also available through plain spark.sql(...) without calling SedonaContext.create first. The later cells rely on this.Confirm geometries reach Python
Confirm spatial functions run on executors
Wherobots Cloud credentials are required, the session did not pick up spark.wherobots.api.key. Confirm the configure-wherobots-key step completed, then restart the notebook kernel — spark-defaults.conf is read only when a session is created.How Wherobots authentication works
WherobotsDB validates your API key at startup and uses it for usage-based billing. Both operations call Wherobots Cloud endpoints that are part of the BYOS feature:- At startup, the JAR authenticates against
POST /apps/authenticate, which returns a workload ID. - While the workload runs, the JAR periodically reports usage heartbeats to
POST /apps/report/{workload_id}.
403 and initialization fails. The same feature grants access to the release JARs. See Before you start.
You can supply the key in either of two ways:
Feature differences from Wherobots Cloud
BYOS provides the WherobotsDB engine on your cluster. Features of the managed Wherobots Cloud platform are not included:- The Wherobots managed catalogs —
wherobots,wherobots_open_data,wherobots_pro_data, and the tutorialexamples_tempcatalog — are not available. Notebooks or jobs that reference them must be pointed at your own catalogs or read public data directly. - The EMR JAR does not bundle Apache Iceberg. Add your own Iceberg runtime and catalog configuration if you need Iceberg tables, appending its extension to
spark.sql.extensionsrather than replacing the Sedona entries. - Runtime conveniences that Wherobots Cloud preconfigures — the Spark checkpoint directory, visualization packages such as SedonaKepler, and pre-installed Python dependencies — must be set up on your cluster yourself. The bootstrap script covers the essentials.
Troubleshooting
ClassNotFoundException, UNRESOLVED_ROUTINE, ST_* functions not recognized, or 'JavaPackage' object is not callable in PySpark
- Confirm both
spark.jarsandspark.yarn.dist.jarsare set as in Configuration JSON, and that the filenames exactly match the files in/jars. A missingspark.jarsis the classic cause when runningpysparkorspark-submitin client mode: the extensions silently fail to load on the driver. - Check the bootstrap log at
<log-uri>/<cluster-id>/node/<instance-id>/bootstrap-actions/1/and confirm/jarswas populated on every node. - If you set classpaths directly, append to Amazon EMR’s defaults rather than replacing them. Overwriting
spark.driver.extraClassPathorspark.executor.extraClassPathat the cluster level removes EMRFS from the classpath and breaks S3 access. Prefer thespark.jarsapproach.
ModuleNotFoundError: No module named 'sedona' — the Python client is not installed into the interpreter PySpark uses. Check the bootstrap log for the wheel-install section, and confirm PY_BIN matches your EMR release: /usr/bin/python3 on EMR 7.8.0, /usr/bin/python3.11 on emr-spark-8.0.0. If you are installing by hand, pass pip the wheel’s path — pip install wherobots-sedona by name cannot resolve, since the package is not on PyPI.
ModuleNotFoundError: No module named 'pandas' — wheels up to and including 1.28.0 did not declare their pandas dependency. When deploying those versions, add a sudo "${PY_BIN}" -m pip install pandas line to the bootstrap script, after every aws command.
Bootstrap fails with Cannot uninstall setuptools ... RECORD file not found — pip is trying to replace the rpm-owned setuptools on Amazon Linux. Wheels up to and including 1.28.0 pinned setuptools>=69, which triggers this. Add --ignore-installed to the bootstrap’s pip install line when deploying those versions. Later releases carry no setuptools pin.
UnsupportedClassVersionError — the cluster is running JDK 8. Use an EMR 7.x or later release, which ships JDK 17. See Version compatibility.
NoSuchMethodError at query time — a Spark or Scala mismatch between the JAR and the EMR release, for example the 4.0_2.13 JAR on emr-7.8.0, which is Spark 3.5 and Scala 2.12. See Version compatibility.
Bootstrap fails with S3 AccessDenied — the EMR EC2 instance profile is missing s3:GetObject on your staging prefix or on the bootstrap script itself. If you modified the bootstrap to use --recursive or sync, it additionally needs s3:ListBucket on the bucket.
Cluster creation fails with VALIDATION_ERROR: Service role ... has insufficient EC2 permissions, and no logs are written — the for-use-with-amazon-emr-managed-policies=true cluster tag is missing. See Create cluster. No instance ever launches, so there is nothing to log.
A failed cluster reports Unknown Error. with no logs — the instance profile cannot write to the log URI. Confirm the s3:PutObject statement from Give Secret Manager Access is present, and that --log-uri ends in a trailing slash.
AccessDenied reading public S3 datasets — Amazon EMR’s S3 filesystem signs every request with the instance profile, and cross-account access requires an identity-policy allow even for publicly readable buckets. Either grant the instance profile read access to those buckets, or read them anonymously with s3a:// URIs plus spark.hadoop.fs.s3a.bucket.<bucket-name>.aws.credentials.provider=org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider.
Authentication errors from SedonaContext.create — confirm spark.wherobots.api.key or WHEROBOTS_API_KEY is set, that the key has not expired, that BYOS is enabled for your Organization, and that your security groups and network policy allow outbound HTTPS to Wherobots Cloud.

