aws-s3

2 posts

slack

From SSH to REST: A Security-Driven Modernization of Slack’s EMR Data Pipelines (opens in new tab)

Slack had more than 700 SSH-based operators running critical EMR workloads, creating security risks, operational failures, and barriers to infrastructure modernization. The company replaced these connections with REST-based job submission across eight data regions without downtime. YARN Distributed Shell was the key enabler for migrating arbitrary command-line jobs that lacked dedicated REST APIs. ## How Slack’s SSH Architecture Developed - Airflow originally connected directly to EMR master nodes using `SSHOperator`. - Over time, teams created more than 700 SSH-based jobs for: - Spark and MapReduce workloads - AWS CLI commands - Custom Python scripts - Data-transfer operations such as `hadoop distcp` - The approach was simple but tightly coupled orchestration workers to production clusters. ## Security and Operational Costs of SSH - Direct SSH access expanded the attack surface. - SSH keys had to be distributed and rotated across orchestration workers. - Auditing required correlating activity across multiple systems. - Permissions became complicated, often involving custom security groups and configurations. - Jobs ran on EMR master nodes, causing resource contention. - Restarted Kubernetes pods could break SSH connections. - Long-running processes could become orphaned “zombie” jobs. - Connection failures made job success or failure difficult to determine. - SSH dependencies blocked Spark-on-Kubernetes, EMR on EKS, AWS child-account migration, and better observability. - Slack’s search-indexing pipeline was especially sensitive because it processed terabytes of data daily and supported search for millions of users. ## REST-Based Job Submission - SSH creates a stateful connection whose failure can leave job status ambiguous. - REST APIs provide a durable, server-managed lifecycle: - `POST` submits a job and returns an ID. - `GET` retrieves its status. - `DELETE` cancels it cleanly. - Clients can crash or restart without terminating the underlying job. - Existing systems such as YARN, Trino, and Snowflake use this model. - YARN provides REST submission for Hadoop, Spark, Hive, and MapReduce workloads, but not arbitrary shell commands. ## YARN Distributed Shell - Spark and Hive already had REST-compatible options through Livy and HiveServer2. - The difficult cases were MapReduce and more than 300 CLI-based jobs. - Slack considered custom wrapper services, Ansible or Salt, and creating a new YARN job type. - These alternatives added complexity, security work, or long-term maintenance. - YARN Distributed Shell—implemented through `ApplicationMaster`—could execute arbitrary scripts inside YARN containers. - It used existing YARN APIs and authentication mechanisms, avoiding a custom security layer. ## The Distributed Shell Workflow - Upload a command script to S3, such as an `aws s3 sync` operation. - Submit a YARN application specifying: - The Distributed Shell application master - The S3 script location - Script metadata such as length and timestamp - YARN then: - Allocates a resource-managed container - Downloads and executes the script - Enforces memory and vCore limits - Provides isolation, retries, cancellation, and centralized logging By using REST submission and YARN Distributed Shell, Slack could remove SSH from its EMR data pipelines while preserving support for both standard data-processing jobs and arbitrary command-line workloads.

slack

Optimizing Our E2E Pipeline (opens in new tab)

Slack optimized its monorepo E2E pipeline by avoiding frontend rebuilds when a pull request contains no frontend changes. Using `git diff` to detect relevant changes and serving recent frontend artifacts from S3 through an internal CDN, the team reduced build frequency by 60% and cut end-to-end pipeline time from roughly 10 minutes to 2 minutes. The changes also lowered storage and compute costs and improved test reliability. ## The Cost of Unnecessary Frontend Builds - Slack’s E2E pipeline validates frontend, backend, database, and service changes before merging into `main`. - Previously, every run rebuilt the frontend, even when a pull request changed only backend or unrelated files. - A typical pipeline included: - About 5 minutes for the frontend build - Deployment to QA - More than 200 E2E tests taking another 5 minutes - With hundreds of pull requests merged daily, redundant builds caused: - Thousands of unnecessary builds each week - Nearly a gigabyte of S3 data per build - Terabytes of duplicate stored artifacts - Significant developer and cloud-compute costs ## Conditional Frontend Builds - Slack used `git diff` with three-dot notation to compare the checked-out branch against `main`. - If frontend files had changed, the pipeline ran a new frontend build. - If no frontend changes were detected, the build step was skipped. - Git analyzed the repository’s more than 100,000 tracked files in only a few seconds. ## Reusing Prebuilt Assets - When a new build was unnecessary, the pipeline located a recent frontend build already stored in AWS S3. - The selected artifact was still in production, ensuring the E2E tests used sufficiently current frontend assets. - An internal CDN served those assets to the QA environment. - S3 naming and asset-management conventions made it possible to find an appropriate artifact in under three seconds on average. ## Results and Additional Benefits - Frontend build frequency fell by 60%. - Average E2E pipeline time dropped from about 10 minutes to 2 minutes. - Monthly savings included hundreds of hours of compute and developer waiting time. - S3 usage decreased by several terabytes per month. - Test flakiness reached its lowest measured level, partly because asset delivery became more consistent. - The work also exposed legacy systems and generated a backlog of future maintenance improvements. Slack’s experience demonstrates that pipelines should not automatically repeat expensive steps when their inputs have not changed. Detecting affected files and reusing trustworthy build artifacts can substantially improve speed, reliability, and cost without requiring a wholesale rewrite of the CI/CD system.