<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[BMC Innovation - Medium]]></title>
        <description><![CDATA[BMC Innovation - Medium]]></description>
        <link>https://medium.com/bmc-digital-it?source=rss----c83eeec4e799---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>BMC Innovation - Medium</title>
            <link>https://medium.com/bmc-digital-it?source=rss----c83eeec4e799---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 09:08:26 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/bmc-digital-it" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Operationalizing Predictive Analytics with Control-M and Vertex AI]]></title>
            <link>https://medium.com/bmc-digital-it/operationalizing-predictive-analytics-with-control-m-and-vertex-ai-1d52044a9c40?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/1d52044a9c40</guid>
            <category><![CDATA[workflow-automation]]></category>
            <category><![CDATA[orchestration]]></category>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[vertex-ai]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Tue, 09 Jun 2026 15:56:49 GMT</pubDate>
            <atom:updated>2026-06-09T15:56:50.901Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*xIp5FFKXhymPxfxbs4Ts7A.jpeg" /></figure><p><strong><em>By Ferwa Zaidi, </em></strong><a href="https://www.linkedin.com/in/samuelduru/"><strong><em>Sam Duru-Nnebue</em></strong></a><strong><em> and </em></strong><a href="https://www.linkedin.com/in/michaeloladugba/"><strong><em>Michael Oladugba</em></strong></a></p><p>In <a href="https://medium.com/bmc-digital-it/operationalizing-s-p-500-analytics-with-control-m-bigquery-and-amazon-quicksight-4f68e27f3f1c"><strong>Phase 1</strong></a> of this series, <em>Operationalizing S&amp;P 500 Analytics with Control-M, BigQuery, and Amazon QuickSight</em>, we focused on building a reliable foundation for analytics. That first phase showed how Control-M orchestrates a multi-cloud ETL pipeline to ingest raw S&amp;P 500 data, cleanse and enrich it in BigQuery, and deliver consistent, up-to-date dashboards in Amazon QuickSight. The outcome was a production-grade descriptive analytics system — automated, auditable, and dependable.</p><p><a href="https://medium.com/bmc-digital-it/operationalizing-s-p-500-analytics-with-control-m-bigquery-and-amazon-quicksight-4f68e27f3f1c">Phase 1</a> answered a fundamental question: <strong>How do we ensure historical market data is always accurate, timely, and ready for analysis?</strong></p><p>But descriptive analytics only explains what has already happened.</p><p>Phase 2 builds directly on that same orchestrated foundation and extends it into <strong>predictive analytics</strong>. Using the cleansed datasets and engineered features from <a href="https://medium.com/bmc-digital-it/operationalizing-s-p-500-analytics-with-control-m-bigquery-and-amazon-quicksight-4f68e27f3f1c">Phase 1</a>, the pipeline now trains, deploys, and runs machine-learning models to generate forward-looking insights — predicted returns, volatility estimates, confidence scores, and buy/sell signals.</p><p>This introduces a new operational challenge. Predictive models must run in the correct order, on fresh and validated data, and complete within strict time windows. A prediction that arrives late or out of sequence is not actionable.</p><p>In Phase 2, Control-M orchestrates the entire predictive analytics lifecycle, coordinating feature engineering in BigQuery, model training and deployment in Vertex AI, daily scoring, and downstream visualization refreshes. Together, Phase 1 and Phase 2 show how enterprise orchestration turns analytics from historical reporting into <strong>reliable, production-ready predictive intelligence</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/575/1*huzaKdUk2LiUb0-_UuOy1A.jpeg" /><figcaption>Full Phase 2 Architecture and Process Flow</figcaption></figure><h3>What’s New in Phase 2?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R_A3Bnn4RhXgPyCOntp2LA.png" /><figcaption>Phase 1 and Phase 2 combined workflow highlighting Phase 2</figcaption></figure><p>Phase 2 introduces several major enhancements across the pipeline:</p><h4>Feature Engineering &amp; Data Quality Checks</h4><p>We begin by validating stock data — addressing missing values, handling outliers, and enforcing consistency across data types. Once validated, we engineer technical indicators such as Moving averages, RSI, MACD, Volatility metrics, Lagged returns.</p><p>These engineered features are stored in BigQuery, making them easily accessible for training and scoring.</p><h4>Model Training and Hyperparameter Tuning</h4><p>To improve prediction accuracy, multiple models were evaluated. In addition to linear regression, we experimented with a Random Forest approach.</p><p>Performance was assessed using <strong>RMSE, R², and MAE</strong>. While Random Forest initially appeared promising, it struggled to generalize and showed signs of overfitting. Linear regression proved more stable and interpretable, effectively capturing the underlying relationships between features and returns.</p><h4>Model Deployment</h4><p>Once trained and validated, the selected model is registered and deployed in <strong>Vertex AI</strong>, enabling consistent execution and scalable scoring.</p><h4>Model Scoring</h4><p>Fresh market data is scored daily, producing Predicted Daily Returns, Predicted Volatility, Confidence Scores, Buy/Sell signals.</p><p>These outputs provide actionable insights while also indicating prediction reliability.</p><h4>Orchestration</h4><p>Control-M orchestrates the entire workflow — managing dependencies, execution order, retries, and monitoring. This ensures the pipeline runs reliably without manual intervention.</p><h4>Visualization</h4><p>Prediction results are surfaced through <strong>Looker Studio dashboards</strong>, allowing business users to monitor trends, volatility, and trading signals in near real time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/442/1*lcebhO-g0JqjgifH7Zre8g.png" /><figcaption>Phase 2 Pipeline Workflow in Control M</figcaption></figure><h3>Control-M Workflow: Step-by-Step Execution</h3><p>In Phase 2, Control-M orchestrates the entire predictive analytics lifecycle as a structured, event-driven workflow. Rather than executing jobs independently, each step is connected through explicit dependencies to ensure data readiness, correctness, and reliable execution order.</p><p>At a high level, the workflow consists of three core Control-M jobs:</p><ol><li><strong>BigQuery Feature Engineering Job</strong></li><li><strong>Vertex AI Pipeline Job</strong></li><li><strong>Looker Studio Refresh Trigger</strong></li></ol><p>Each job runs only when its upstream dependency has completed successfully.</p><p><strong><em>Note:</em></strong><em><br>All JSON definitions shown in this blog are snippets for illustration. They capture only the key parts of each job (e.g., Type, Src, Dest, FileTransfers, SQLStatement). The full JSON files, with complete scheduling logic, events, and metadata, are available on our GitHub repo </em><a href="https://github.com/controlm-samples/sp500_phase2"><em>here</em></a><em>.</em></p><h4>Step 1: BigQuery Feature Engineering Job</h4><p>The workflow begins with a <strong>GCP BigQuery job</strong> managed by Control-M.</p><p>This job transforms the cleaned S&amp;P 500 dataset (sp500_clean) into a fully engineered feature table (sp500_features). Using SQL window functions and analytical calculations, it generates Daily returns, Moving averages (MA-7, MA-30), Volatility metrics, RSI and MACD indicators, Bollinger Bands and EMA features. The result is a feature-rich dataset stored in BigQuery and ready for model training and scoring.</p><p>Once the feature table is successfully created, Control-M emits an event that signals downstream processing can begin.</p><pre>&quot;BigQuery-Job&quot; : {<br>      &quot;Type&quot; : &quot;Job:GCP BigQuery&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SP500-BIGQUERY&quot;,<br>      &quot;Project Name&quot; : &quot;sso-gcp-dba-ctm4-pub-cc10274&quot;,<br>      &quot;Dataset Name&quot; : &quot;sp500_dataset&quot;,<br>      &quot;Action&quot; : &quot;Query&quot;,<br>      &quot;Run Select Query and Copy to Table&quot; : &quot;unchecked&quot;,<br>      &quot;SQL Statement&quot; : &quot;CREATE OR REPLACE TABLE `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_features` AS%4ESELECT%4EDATE(date) AS date,%4Eopen,%4Ehigh,%4Elow,%4Eclose,%4Evolume,%4EName,%4ESAFE_DIVIDE(close - LAG(close) OVER (PARTITION BY Name ORDER BY DATE(date)),LAG(close) OVER (PARTITION BY Name ORDER BY DATE(date))) AS daily_return,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma_7,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS ma_30,%4ESTDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS volatility_7d,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS RSI_14,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 11 PRECEDING AND CURRENT ROW)%4E-%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 25 PRECEDING AND CURRENT ROW) AS MACD,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 8 PRECEDING AND CURRENT ROW) AS MACD_signal,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW)%4E+%4E2 * STDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS bb_upper,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS bb_middle,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW)%4E-%4E2 * STDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS bb_lower,%4EAVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS EMA20%4EFROM `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_clean`;%4E&quot;,<br>      &quot;Copy Operation Type&quot; : &quot;Copy&quot;,<br>      &quot;Show Load Options&quot; : &quot;unchecked&quot;,<br>      &quot;Host&quot; : &quot;vertex-agent.ctmgcpagents.com&quot;,<br>      &quot;CreatedBy&quot; : &quot;&lt;creator email&gt;&quot;,<br>      &quot;Description&quot; : &quot;This job further proccessses the clean data and feature engineering&quot;,<br>      &quot;RunAs&quot; : &quot;SP500-BIGQUERY&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToAdd&quot; : {<br>        &quot;Type&quot; : &quot;AddEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;GCP_BigQuery_Job_1-TO-GCP_Vertex_AI_Job_300&quot;<br>        } ]<br>      }<br>    },</pre><pre>CREATE OR REPLACE TABLE `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_features` AS SELECT DATE(date) AS date, open, high, low, close, volume, Name, SAFE_DIVIDE(close - LAG(close) OVER (PARTITION BY Name ORDER BY DATE(date)),LAG(close) OVER (PARTITION BY Name ORDER BY DATE(date))) AS daily_return, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma_7, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS ma_30, STDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS volatility_7d, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS RSI_14, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) - AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 25 PRECEDING AND CURRENT ROW) AS MACD, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 8 PRECEDING AND CURRENT ROW) AS MACD_signal, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) + 2 * STDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS bb_upper, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS bb_middle, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) - 2 * STDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS bb_lower, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS EMA20 FROM `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_clean`;</pre><h4>Step 2: Vertex AI Pipeline Job</h4><p>After feature engineering completes, Control-M triggers a <strong>Vertex AI pipeline</strong> using the GCP Vertex AI plugin.</p><p>This pipeline executes a multi-stage machine learning workflow that includes:</p><ul><li>Loading engineered features from BigQuery</li><li>Preprocessing and scaling data</li><li>Training a regression model</li><li>Registering and deploying the model to a Vertex AI endpoint</li><li>Scoring fresh market data</li><li>Writing prediction results back to BigQuery</li></ul><p>Because the entire pipeline is launched as a single Control-M job, retries, failures, and execution status are centrally monitored and managed.</p><p>When the Vertex AI pipeline completes successfully, Control-M raises another event indicating that prediction results are available for consumption.</p><h4>Step 3: Looker Studio Refresh Trigger</h4><p>The final step in the workflow is a <strong>GCP Cloud Function job</strong> that represents a dashboard refresh event.</p><p>In production environments, BI tools such as Looker Studio typically refresh automatically when underlying data sources update. However, from an orchestration perspective, Control-M still plays a critical role by explicitly marking the completion of the analytics pipeline.</p><p>This job acts as a logical boundary between <strong>data production</strong> and <strong>data consumption</strong>, signaling that:</p><ul><li>Predictions have been generated</li><li>Results are stored in BigQuery</li><li>Dashboards are ready to reflect the latest insights</li></ul><p>From an operational standpoint, this makes the workflow auditable, traceable, and complete.</p><pre>&quot;Looker-refresh-job&quot; : {<br>      &quot;Type&quot; : &quot;Job:GCP Functions&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;GCFSTD&quot;,<br>      &quot;Function Parameters&quot; : &quot;URL Parameters&quot;,<br>      &quot;Get Logs&quot; : &quot;unchecked&quot;,<br>      &quot;att2&quot; : &quot;\&quot;filter\&quot;:\&quot;labels.execution_id:&quot;,<br>      &quot;att3&quot; : &quot;\&quot;orderBy\&quot;: \&quot;timestamp desc\&quot;,   \&quot;pageSize\&quot;: 1000 }&quot;,<br>      &quot;Project ID&quot; : &quot;sso-gcp-dba-ctm4-pub-cc10274&quot;,<br>      &quot;Location&quot; : &quot;us-west2&quot;,<br>      &quot;Function Name&quot; : &quot;looker-refresh&quot;,<br>      &quot;Host&quot; : &quot;vertex-agent.ctmgcpagents.com&quot;,<br>      &quot;CreatedBy&quot; : &quot;&lt;creator email&gt;&quot;,<br>      &quot;Description&quot; : &quot;This job triggers the GCP function that refreshes the looker dashboard&quot;,<br>      &quot;RunAs&quot; : &quot;GCFSTD&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;GCP_Vertex_AI_Job_300-TO-Looker_refresh&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;GCP_Vertex_AI_Job_300-TO-Looker_refresh&quot;<br>        } ]<br>      }<br>    },</pre><h4>Why This Workflow Matters</h4><p>By modeling the pipeline as a sequence of dependent Control-M jobs, Phase 2 achieves:</p><ul><li>Deterministic execution order</li><li>Clear operational visibility</li><li>Reliable daily prediction delivery</li><li>Separation of data engineering, ML, and visualization concerns</li></ul><p>Instead of treating machine learning as an ad-hoc process, the workflow becomes a production-grade system that can be scheduled, monitored, and scaled like any other enterprise workload.</p><h3>Business Use Case: Why Predictive Modeling Matters</h3><p>Financial organizations rely on timely, accurate insights to navigate volatility and assess risk. While historical dashboards remain valuable, modern markets demand predictive intelligence.</p><p>This workflow enables:</p><ul><li><strong>Proactive risk management</strong> using volatility forecasts</li><li><strong>More informed investment decisions</strong> driven by predicted returns</li><li><strong>Quant-driven strategy refinement</strong> using model outputs stored in BigQuery</li><li><strong>Operational consistency</strong>, ensuring predictions arrive reliably each day</li><li><strong>Cross-cloud collaboration</strong> across GCP, AWS, and internal systems</li></ul><p>By transforming raw market data into predictive intelligence, the system supports faster decisions and deeper market understanding.</p><h3>Control-M Plugins and Job Types Used</h3><p>Control-M acts as the orchestration backbone, leveraging multiple job types:</p><h4>1. GCP BigQuery Jobs</h4><ul><li>Feature table creation</li><li>Data validation</li><li>Writing predictions back to BigQuery</li></ul><h4>2. Control-M MFT (Managed File Transfer)</h4><ul><li>Secure file movement between S3 and GCS</li><li>Automated ingestion triggers</li></ul><h4>3. Python &amp; Bash Jobs</h4><ul><li>Trigger Vertex AI pipelines</li><li>Execute scoring logic</li><li>Invoke cloud APIs</li></ul><h4>4. REST API Jobs</h4><ul><li>Register and deploy Vertex AI models</li><li>Trigger dashboard refresh events in Looker Studio or Quicksight</li><li>Perform endpoint health checks</li></ul><h4>5. AWS QuickSight Plugin</h4><ul><li>Refresh dashboard datasets</li><li>Validate analytics visibility</li></ul><h4>6. File Watchers</h4><ul><li>Detect new market data arrivals</li><li>Automatically launch downstream ML jobs</li></ul><p>Together, these capabilities create a unified orchestration layer across data engineering, machine learning, and business intelligence.</p><h3>The Pipeline Workflow</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/628/1*1ibAJyygKvEmbH-eRfo-mw.png" /><figcaption>Vertex AI Pipeline Workflow</figcaption></figure><p>The Phase 2 pipeline consists of four major steps:</p><ol><li>Load and Preprocess Data</li><li>Model Training</li><li>Register and Deploy Model</li><li>Model Scoring</li></ol><h4>High-Level Goals</h4><ul><li><strong>Feature Engineering &amp; Data Quality Checks: </strong>Ensuring that the dataset is clean and robust, making it ready for model training. This step is critical to ensure accurate predictions.</li><li><strong>Training and Hyperparameter Tuning: </strong>Experimenting various algorithms and fine-tuning hyperparameters to find the best model for our task.</li><li><strong>Model Deployment in Vertex AI: </strong>Registering and deploying the model in <strong>Vertex AI</strong>, enabling real-time prediction and scalability.</li><li><strong>Model Scoring and Reporting via Looker Studio: </strong>Making daily predictions and updating the <strong>Looker Studio</strong> dashboards with new insights, such as <strong>predicted daily returns</strong>, <strong>volatility</strong>, and <strong>buy/sell signals</strong>.</li></ul><h3>Pipeline Steps in Detail</h3><h4>Step 1: Load and Preprocess Data</h4><p>Raw S&amp;P 500 data is fetched from BigQuery, cleaned, and enriched with engineered features. Processed datasets are saved to GCS for downstream training.</p><pre>from google.cloud import bigquery, storage <br>import pandas as pd <br>from sklearn.model_selection import train_test_split <br>from sklearn.impute import SimpleImputer <br>from sklearn.preprocessing import StandardScaler <br>import joblib <br>import os <br><br>@dsl.component( <br>     base_image=&quot;python:3.9&quot;, <br>     packages_to_install=[ <br>         &quot;google-cloud-bigquery&quot;, <br>         &quot;google-cloud-storage&quot;, <br>         &quot;pandas&quot;, <br>         &quot;scikit-learn&quot;, <br>         &quot;joblib&quot;, <br>        &quot;db-dtypes&quot; <br>     ] <br>) <br>def load_preprocess_op(project_id: str, query: str, bucket_name: str) -&gt; str: <br>    bq = bigquery.Client(project=project_id) <br>    df = bq.query(query).to_dataframe()<br>  <br>    # Feature engineering and preprocessing... <br>    # After preprocessing, save the dataset for further training. <br>    # Return GCS path for further use</pre><h4>Step 2: Train Model</h4><p>The preprocessed data is used to train the selected model, which is then saved to GCS.</p><pre>from google.cloud import storage <br>from sklearn.linear_model import LinearRegression <br>from sklearn.metrics import mean_squared_error <br>import joblib <br>import os<br><br>@dsl.component( <br>    base_image=&quot;python:3.9&quot;, <br>    packages_to_install=[ <br>        &quot;google-cloud-storage&quot;, <br>        &quot;scikit-learn&quot;, <br>        &quot;joblib&quot; <br>    ] <br>) <br>def train_model_op(processed_data_path: str, bucket_name: str) -&gt; str: <br>    # Train model and save to GCS <br>    storage_client = storage.Client() <br>    bucket = storage_client.bucket(bucket_name) <br>    # Load preprocessed data and train model... <br>    return f&quot;gs://{bucket_name}/models&quot;</pre><h4>Step 3: Register and Deploy Model</h4><p>Once the model is trained, we register it with <strong>Vertex AI</strong> and deploy it to an endpoint. This will allow us to use the model for real-time predictions.</p><pre>from google.cloud import aiplatform <br>@dsl.component( <br>    base_image=&quot;python:3.9&quot;, <br>    packages_to_install=[&quot;google-cloud-aiplatform&quot;] <br>) <br>def register_and_deploy_model_op(model_path: str, project_id: str, location: str) -&gt; str: <br>    # Initialize Vertex AI and deploy model <br>    aiplatform.init(project=project_id, location=location) <br>    model = aiplatform.Model.upload( <br>        display_name=&quot;sp500-linear-regression-model-v1&quot;, <br>        artifact_uri=model_path, <br>        serving_container_image_uri=&quot;us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-3:latest&quot;, <br>    ) <br>    endpoint = model.deploy( <br>        deployed_model_display_name=&quot;sp500-endpoint&quot;, <br>        machine_type=&quot;n1-standard-2&quot; <br>    ) <br>    return endpoint.resource_name</pre><h4>Step 4: Model Scoring</h4><p>Fresh data is scored using the deployed model and results are written back to BigQuery.</p><pre>from google.cloud import aiplatform, bigquery <br>import pandas as pd <br>import numpy as np <br>from sklearn.impute import SimpleImputer <br>from sklearn.preprocessing import StandardScaler<br><br>@dsl.component( <br>    base_image=&quot;python:3.9&quot;, <br>    packages_to_install=[ <br>        &quot;google-cloud-aiplatform&quot;, <br>        &quot;google-cloud-bigquery&quot;, <br>        &quot;pandas&quot;, <br>        &quot;numpy&quot;, <br>        &quot;scikit-learn&quot; <br>    ] <br>) <br>def online_predict_op(endpoint_id: str, project_id: str) -&gt; str: <br>    # Load fresh data from BigQuery and score with deployed model <br>    endpoint = aiplatform.Endpoint(endpoint_id) <br>    df = bigquery.Client(project=project_id).query(&quot;SELECT * FROM ...&quot;).to_dataframe() <br>    return &quot;Predictions uploaded&quot;</pre><p>Once the model was deployed, it was used to generate predictions on fresh incoming data. Each prediction was evaluated using multiple factors, including predicted daily return, volatility, and confidence score. This scoring step runs as part of a structured workflow, ensuring predictions are generated consistently whenever new data becomes available.</p><p>We implemented a straightforward rules-based approach to generate buy and sell signals. A <strong>buy</strong> signal is triggered when the predicted daily return exceeds 0.01; the confidence score is greater than 0.8, and the predicted volatility remains below 0.05. Conversely, when predicted returns fall below 0.01, a <strong>sell</strong> signal is issued. The execution of this logic and the persistence of results back into BigQuery are coordinated as part of the automated pipeline, ensuring reliable and repeatable signal generation without manual intervention.</p><h3>Results: Turning Analytics into Actionable Forecasts</h3><p>By the end of Phase 2, the system can:</p><ul><li>Predict daily returns for every S&amp;P 500 symbol</li><li>Estimate volatility</li><li>Assign confidence scores</li><li>Generate buy / sell signals automatically</li><li>Feed predictions into BI dashboards</li><li>Run continuously via Control-M orchestration</li></ul><p>This modernizes investment research — allowing analysts to evaluate model-driven signals alongside live market data.</p><h3>Why Control-M is essential for orchestrating Predictive Analytics</h3><p>As machine learning pipelines become more complex, managing them manually becomes nearly impossible. Control-M provides the foundation for reliable, scalable, and fully automated execution of the Phase 2 workflow. Control-M contributes value in several keyways:</p><ol><li><strong>End-to-end visibility</strong> into every stage of the pipeline</li><li><strong>Advanced dependency management</strong> ensuring correct execution order</li><li><strong>SLA monitoring &amp; alerting</strong> for consistent delivery of predictions</li><li><strong>Hybrid and multi-cloud orchestration</strong> across GCP, AWS, and on-prem systems</li><li><strong>Error handling and auto-recovery</strong> to support production-grade reliability</li><li><strong>Reusable, versioned workflows</strong> that work across dev, QA, and prod</li></ol><p>Control-M becomes the operational backbone of the predictive analytics system — enabling trust, scalability, and reliability.</p><h3>Business Outcomes at a Glance</h3><ul><li><strong>Daily predictive insights</strong> into returns, volatility, and trade signals</li><li><strong>80–90% reduction</strong> in manual data preparation and scoring tasks</li><li><strong>Guaranteed SLA delivery</strong> of predictions via Control-M orchestration</li><li><strong>Cross-cloud integration</strong> enabling seamless BigQuery → Vertex AI → QuickSight analytics</li><li><strong>Full auditability</strong> and compliance for ML operations</li><li><strong>Scalable foundation</strong> for more advanced predictive models in future phases.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*sTFuRJTgYb_CvJt0mFnBIA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*q3P1PfTDXt4EZ4NPDXsfGg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Y7DqdzIL934QLf9e_-StVg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*TLVGjNE6JiZygltb3Y2V1Q.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ePSF0rTfK92Ql_3eNtBKsA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/816/1*rX5jNPJlBSv3hRXJEk-USQ.png" /><figcaption>Dashboard output in Looker Studio</figcaption></figure><h3>Visualization &amp; Predictive Outputs</h3><p>Once the Phase 2 pipeline completes, prediction results are written to BigQuery and automatically surfaced in Looker Studio. These dashboards represent the final output of the orchestrated workflow, translating model predictions into actionable insights.</p><h4>Predicted Daily Return Over Time</h4><p>This time-series chart shows predicted daily returns for multiple S&amp;P 500 stocks across time. It highlights how the model’s predictions evolve under different market conditions, making it easier to observe trends, volatility spikes, and periods of stability. Because predictions are generated as part of an automated pipeline, the chart always reflects the most recent scoring run.</p><h4>Predicted Gainers</h4><p>This bar chart ranks stocks by their predicted daily return. It provides a quick view of potential short-term outperformers identified by the model, allowing analysts to focus attention on stocks with the strongest predicted upside.</p><h4>Signal Distribution: Buy vs Sell</h4><p>This donut chart summarizes the proportion of Buy and Sell signals generated by the scoring logic. Signals are derived using predicted return, confidence score, and volatility thresholds. The chart offers a high-level view of overall market sentiment inferred by the pipeline.</p><h4>Volatility Breakdown by Entity</h4><p>This visualization shows predicted volatility distributed across individual stocks. It helps identify which entities carry higher uncertainty, adding important risk context alongside predicted returns.</p><h4>Predicted Daily Return by Entity</h4><p>This comparison chart displays predicted returns across stocks. It enables side-by-side evaluation of expected performance, making relative strength easier to assess at a glance.</p><h4>Predicted Volatility by Entity</h4><p>This chart ranks stocks by predicted volatility. When used alongside return predictions, it supports risk-aware analysis by highlighting where higher returns may also come with higher uncertainty.</p><h3>From Orchestration to Insight</h3><p>These dashboards are not refreshed manually. They are the direct outcome of an end-to-end orchestrated workflow:</p><ul><li>Control-M coordinates data preparation and model execution</li><li>Vertex AI generates predictions at scale</li><li>BigQuery stores scoring results</li><li>Looker Studio reflects updates automatically</li></ul><p>Together, these components demonstrate how orchestration turns predictive analytics into a reliable, production-ready insight delivery system.</p><h3>Conclusion</h3><p>In Phase 2, we built an automated pipeline that spans feature engineering, model training, deployment, and scoring — all orchestrated reliably through Control-M.</p><p>By integrating Vertex AI with structured orchestration, predictive analytics becomes a dependable operational capability rather than an experimental exercise. This approach enables deeper market insight, faster decision-making, and a scalable foundation for future innovation.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1d52044a9c40" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/operationalizing-predictive-analytics-with-control-m-and-vertex-ai-1d52044a9c40">Operationalizing Predictive Analytics with Control-M and Vertex AI</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Streamlining Machine Learning Workflows with Control-M and Amazon SageMaker]]></title>
            <link>https://medium.com/bmc-digital-it/title-streamlining-machine-learning-workflows-with-control-m-and-amazon-sagemaker-1a7be0c2bce4?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/1a7be0c2bce4</guid>
            <category><![CDATA[amazon-sagemaker]]></category>
            <category><![CDATA[control-m]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Thu, 16 Oct 2025 18:27:57 GMT</pubDate>
            <atom:updated>2025-10-16T18:27:53.227Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aXZ6Mdc-R_6Wm33DnQnrYg.jpeg" /></figure><p>By: <a href="https://www.linkedin.com/in/sunilbemarkar/">Sunil Bemarkar</a> and <a href="https://www.linkedin.com/in/michaeloladugba/">Michael Oladugba</a></p><p>In today’s fast-paced digital landscape, the ability to harness the power of artificial intelligence (AI) and machine learning (ML) is crucial for businesses aiming to gain a competitive edge. Amazon SageMaker is a game-changing ML platform that empowers businesses and data scientists to seamlessly navigate the development of complex AI models. One of its standout features is its end-to-end ML pipeline, which streamlines the entire process from data preparation to model deployment. Amazon SageMaker’s integrated Jupyter Notebook platform enables collaborative and interactive model development, while its data labeling service simplifies the often-labor-intensive task of data annotation.</p><p>It also boasts an extensive library of pre-built algorithms and deep learning frameworks, making it accessible to both newcomers and experienced ML practitioners. Amazon SageMaker’s managed training and inference capabilities provide the scalability and elasticity needed for real-world AI deployments. Moreover, its automatic model tuning, and robust monitoring tools enhance the efficiency and reliability of AI models, ensuring they remain accurate and up-to-date over time. Overall, Amazon SageMaker offers a comprehensive, scalable, and user-friendly ML environment, making it a top choice for organizations looking to leverage the potential of AI.</p><h3><strong>Bringing Amazon SageMaker and Control-M together</strong></h3><p>Amazon SageMaker simplifies the entire ML workflow, making it accessible to a broader range of users, including data scientists and developers. It provides a unified platform for building, training, and deploying ML models. However, to truly harness the power of Amazon SageMaker, businesses often require the ability to orchestrate and automate ML workflows and integrate them seamlessly with other business processes. This is where Control-M from BMC comes into play.</p><p>Control-M is a versatile application and data workflow orchestration platform that allows organizations to automate, monitor, and manage their data and AI-related processes efficiently. It can seamlessly integrate with SageMaker to create a bridge between AI modeling and deployment and business operations.</p><p>In this blog, we’ll explore the seamless integration between Amazon SageMaker and Control-M and the transformative impact it can have on businesses.</p><p>Amazon SageMaker empowers data scientists and developers to create, train, and deploy ML models across various environments — on-premises, in the cloud, or on edge devices. An end-to-end data pipeline will include more than just Amazon SageMaker’s AI and ML functionality, where data gets ingested from multiple sources, transformed, aggregated etc., before training a model and executing AI/ML pipelines with Amazon SageMaker. Control-M is often used for automating and orchestrating end-to-end data pipelines.</p><p>Here, we will specifically focus on integrating Amazon SageMaker with Control-M. When you have Amazon SageMaker jobs embedded in your data pipeline or complex workflow orchestrated by Control-M, you can harness the capabilities of Control-M for Amazon SageMaker to efficiently execute an end-to-end data pipeline that it also includes Amazon SageMaker pipelines.</p><h3><strong>Key capabilities</strong></h3><p>Control-M for Amazon SageMaker provides:</p><ul><li><strong>Secure connectivity:</strong> Connect to any Amazon SageMaker endpoint securely, eliminating the need to provide authentication details explicitly</li><li><strong>Unified scheduling:</strong> Integrate Amazon SageMaker jobs seamlessly with other Control-M jobs within a single scheduling environment, streamlining your workflow management</li><li><strong>Pipeline execution:</strong> Execute Amazon SageMaker pipelines effortlessly, ensuring that your ML workflows run smoothly</li><li><strong>Monitoring and SLA management:</strong> Keep a close eye on the status, results, and output of Amazon SageMaker jobs within the Control-M Monitoring domain and attach service level agreement (SLA) jobs to your Amazon SageMaker jobs for precise control</li><li><strong>Advanced capabilities:</strong> Leverage all Control-M capabilities, including advanced scheduling criteria, complex dependencies, resource pools, lock resources, and variables to orchestrate your ML workflows effectively</li><li><strong>Parallel execution:</strong> Run up to 50 Amazon SageMaker jobs simultaneously per agent, allowing for efficient job execution at scale</li></ul><h3><strong>Control-M for Amazon SageMaker compatibility</strong></h3><p>Before diving into how to set up Control-M for Amazon SageMaker, it’s essential to ensure that your environment meets the compatibility requirements:</p><ul><li>Control-M/EM: version 9.0.20.200 or higher</li><li>Control-M/Agent: version 9.0.20.200 or higher</li><li>Control-M Application Integrator: version 9.0.20.200 or higher</li><li>Control-M Web: version 9.0.20.200 or higher</li><li>Control-M Automation API: version 9.0.20.250 or higher</li></ul><p><em>Please ensure you have the required installation files for each prerequisite available.</em></p><h3><strong>A real-world example:</strong></h3><p>The Abalone Dataset, sourced from the UCI Machine Learning Repository, has been frequently used in ML examples and tutorials to predict the age of abalones based on various attributes such as size, weight, and gender. The age of abalones is usually determined through a physical examination of their shells, which can be both tedious and intrusive. However, with ML, we can predict the age with considerable accuracy without resorting to physical examinations.</p><p>For this exercise, we used the <a href="https://docs.aws.amazon.com/sagemaker/latest/dg/define-pipeline.html">Abalone tutorial</a> provided by AWS. This tutorial efficiently walks users through the stages of data preprocessing, training, and model evaluation using Amazon SageMaker.</p><p>After understanding the tutorial’s nuances, we trained the Amazon SageMaker model with the Abalone Dataset, achieving satisfactory accuracy. Further, we created a comprehensive continuous integration and continuous delivery (CI/CD) pipeline that automates model retraining and endpoint updates. This not only streamlined the model deployment process but also ensured that the Amazon SageMaker endpoint for inference was always up-to-date with the latest trained model.</p><h3><strong>Setting up Control-M for Amazon SageMaker</strong></h3><p>Now, let’s walk through how to set up Control-M for Amazon SageMaker, which has three main steps:</p><ol><li>Creating a connection profile that Control-M will use to connect to the Amazon SageMaker environment</li><li>Defining an Amazon SageMaker job in Control-M that will define what we want to run and monitor within Amazon SageMaker</li><li>Executing an Amazon SageMaker pipeline with Control-M</li></ol><p><strong>Step 1: Create a connection profile</strong></p><p>To begin, you need to define a connection profile for Amazon SageMaker, which contains the necessary parameters for authentication and communication with SageMaker. Two authentication methods are commonly used, depending on your setup.</p><p>Example 1: Authentication with AWS access key and secret</p><pre>{<br>  &quot;AWS-SAGEMAKER&quot;:{<br>    &quot;Type&quot;: &quot;ConnectionProfile:AWS SageMaker&quot;,<br>    &quot;SageMaker URL&quot;: &quot;https://sagemaker.us-east-2.amazonaws.com&quot;,<br>    &quot;AWS Region&quot;: &quot;us-east-2&quot;,<br>    &quot;Authentication&quot;: &quot;Secret&quot;,<br>    &quot;AWS Access key&quot;: &quot;&quot;,<br>    &quot;AWS Secret&quot;: &quot;&quot;,<br>    &quot;Connection Timeout&quot;: &quot;100&quot;,<br>    &quot;Description&quot;: &quot;&quot;,<br>    &quot;Centralized&quot;: true<br>  }<br>}</pre><p>Figure 1. Authentication with AWS access key and secret</p><p>Example 2: Authentication with AWS IAM role from EC2 instance</p><pre>{<br>  &quot;AWS_SAGEMAKER_IAM&quot;: {<br>    &quot;Type&quot;: &quot;ConnectionProfile:AWS SageMaker&quot;,<br>    &quot;SageMaker URL&quot;: &quot;&lt;SAGEMAKER_URL&quot;,<br>    &quot;AWS Region&quot;: &quot;&lt;AWS_REGION&quot;,<br>    &quot;Authentication&quot;: &quot;NOSecret&quot;,<br>    &quot;IAM Role&quot; : &quot;&lt;IAM_ROLE_NAME&gt;&quot;,<br>    &quot;Connection Timeout&quot;: &quot;100&quot;,<br>    &quot;Description&quot;: &quot;&quot;,<br>    &quot;Centralized&quot;: true<br>  }<br>}</pre><p>Figure 2. Authentication with AWS IAM role .</p><p>Choose the authentication method that aligns with your environment. It is important to specify the Amazon SageMaker job type exactly as shown in the examples above. Please note that Amazon SageMaker is case-sensitive, so make sure to use the correct capitalization.</p><p><strong>Step 2: Define an Amazon SageMaker job</strong></p><p>Once you’ve set up the connection profile, you can define an Amazon SageMaker job type within Control-M, which type enables you to execute Amazon SageMaker pipelines effectively.</p><pre>{<br>  &quot;mol-sagemaker-folder&quot;: {<br>  &quot;Type&quot;: &quot;Folder&quot;,<br>  &quot;ControlmServer&quot;: &quot;&quot;,<br>  &quot;OrderMethod&quot;: &quot;Manual&quot;,<br>  &quot;RunAs&quot;: &quot;&quot;,<br>  &quot;CreatedBy&quot;: &quot;&quot;,<br>  &quot;Application&quot;: &quot;&quot;,<br>  &quot;DaysKeepActiveIfNotOk&quot;: &quot;1&quot;,<br><br>  &quot;AWS SageMaker_Job_2&quot;: {<br>    &quot;Type&quot;: &quot;Job:AWS SageMaker&quot;,<br>    &quot;ConnectionProfile&quot;: &quot;AWS-SAGEMAKER&quot;,<br>    &quot;Pipeline Name&quot;: &quot;&quot;,<br>    &quot;Add Parameters&quot;: &quot;unchecked&quot;,<br>    &quot;Retry Pipeline Execution&quot;: &quot;unchecked&quot;,<br>    &quot;Host&quot;: &quot;&quot;,<br>    &quot;CreatedBy&quot;: &quot;&quot;,<br>    &quot;RunAs&quot;: &quot;AWS-SAGEMAKER&quot;<br>    }<br>  }<br>}</pre><p>Figure 3. Example AWS SageMaker job definition.</p><p>In this example, we’ve defined an Amazon SageMaker job, specifying the connection profile to be used (“AWS-SAGEMAKER”). You can configure additional parameters such as the pipeline name, idempotency token, parameters to pass to the job, retry settings, and more. For a detailed understanding and code snippets, please refer to the <a href="https://www.bmc.com/it-solutions/control-m-integrations/aws-sagemaker.html">BMC official documentation for Amazon SageMaker</a></p><p><strong>Step 3: Executing the Amazon SageMaker pipeline with Control-M</strong></p><p>It’s essential to note that the pipeline name and endpoint are mandatory JSON objects within the pipeline configuration. By executing the “ctm run” command on the <em>pipeline.json</em> file, it activates the pipeline’s execution within AWS.</p><p>First, we run<em> “ctm build sagemakerjob.json” </em>to validate our JSON configuration and then the<em> “ctm run sagemakerjob.json” </em>command to execute the pipeline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/975/1*FsNz9phzOlo48svE7rZvkg.png" /></figure><p>Figure 4. Launching Amazon SageMaker job.</p><p>As seen in the screenshot above the <em>“ctm run”</em> command has launched the Amazon SageMaker job. The next screenshot shows the pipeline running from the Amazon SageMaker console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/855/1*CM2i-pkX0yaGsIPECWIkfQ.png" /></figure><p>Figure 5. View of data pipeline running in Amazon SageMaker console.</p><p>In the Control-M monitoring domain, users have the ability to view job outputs. This allows for easy tracking of pipeline statuses and provides insights for troubleshooting any job failures.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/975/1*z_OBcWR6Zlq3imO77gPhgg.png" /></figure><p>Figure 6. View of Amazon SageMaker job output from Control-M Monitoring domain.</p><p><strong>Summary</strong></p><p>In this blog, we demonstrated how to integrate Control-M with Amazon SageMaker to unlock the full potential of AWS ML services, orchestrating them effortlessly into your existing application and data workflows. This fusion not only eases the management of ML jobs but also optimizes your overall automation processes.</p><p>Stay tuned for more blogs on Control-M (self-hosted and SaaS) integrations! To learn more about Control-M integrations, visit our <a href="https://www.bmc.com/it-solutions/control-m-integrations.html#&amp;sortCriteria=recommended&amp;category=mp">website</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1a7be0c2bce4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/title-streamlining-machine-learning-workflows-with-control-m-and-amazon-sagemaker-1a7be0c2bce4">Streamlining Machine Learning Workflows with Control-M and Amazon SageMaker</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Operationalizing S&P 500 Analytics with Control-M, BigQuery, and Amazon QuickSight]]></title>
            <link>https://medium.com/bmc-digital-it/operationalizing-s-p-500-analytics-with-control-m-bigquery-and-amazon-quicksight-4f68e27f3f1c?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/4f68e27f3f1c</guid>
            <category><![CDATA[data-engineering]]></category>
            <category><![CDATA[business-intelligence]]></category>
            <category><![CDATA[control-m]]></category>
            <category><![CDATA[etl-pipeline]]></category>
            <category><![CDATA[big-data]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Thu, 16 Oct 2025 18:26:42 GMT</pubDate>
            <atom:updated>2026-06-10T16:30:20.721Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e2TIfw61xFRfTJmP79duvw.png" /></figure><p><strong><em>By </em></strong><a href="https://www.linkedin.com/in/samuelduru/"><strong><em>Sam Duru-Nnebue </em></strong></a><strong><em>and </em></strong><a href="https://www.linkedin.com/in/michaeloladugba/"><strong><em>Michael Oladugba</em></strong></a></p><p>A trade analyst starts their morning scanning dashboards of the S&amp;P 500. <br>To them, it’s all about candlesticks, moving averages, gainers, decliners, and volatility trends — ready at a glance, updated to the latest trading day.</p><p>What’s not visible is the hidden machinery behind those charts. The data isn’t magically there, it’s the result of a carefully choreographed ETL process: ingesting raw datasets from multiple sources, transforming them through cleansing and enrichment, calculating market indicators, and loading the results into analytical tables. From there, scheduled refresh operations push the latest figures into the dashboarding layer, ensuring the analyst always sees timely, accurate, and consistent market views.</p><p>In production environments — especially at enterprise scale — achieving speed, accuracy, and reliability across multi-cloud infrastructure requires more than just scripts or manual steps. It demands orchestration: a coordinated execution of every job, file transfer, and query that powers the dashboard.</p><h3>Business Goal and Objectives</h3><p>Build an automated ETL pipeline that ingests, cleans, and enriches S&amp;P 500 data, delivering it to Amazon QuickSight dashboards via Google BigQuery — fully orchestrated with Control-M.</p><h3>Process Flow:</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*OojVV8HoWhaOiwj0aRl-cw.png" /></figure><h4>Key Considerations</h4><ul><li>Data arrives in raw CSV format with inconsistent formatting</li><li>Historical data contains missing or malformed records</li><li>Engineering metrics (like moving averages) must be calculated</li><li>The pipeline must be modular and auditable</li><li>Final outputs must support analytics and ML models downstream</li></ul><h3>Use Case and Dataset Background</h3><p>This solution processes historical daily prices of S&amp;P 500 companies over a 5-year period, obtained from this Kaggle dataset.</p><h4>Use Case Summary</h4><p>We transform unstructured CSV data into a clean, analytics-ready BigQuery table enriched with key financial indicators. The output powers dashboards and downstream from this would support ML pipelines for training and evaluation of models. We plan to cover the ML portion in a different blog.</p><h4>Dataset Overview</h4><ul><li>Source: Kaggle — S&amp;P 500 stock data</li><li>Raw Fields: Date, Open, Close, High, Low, Volume, Ticker</li><li>Final Fields (added):</li></ul><p><em>— Daily Return = (Close — Open) / Open</em></p><p><em>— 7-Day Moving Average (MA_7)</em></p><p><em>— 30-Day Moving Average (MA_30)</em></p><p><em>— 7-Day Volatility (standard deviation of Close)</em></p><h3>Solution Architecture</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GkXXr2N76y7h6AoCFQ4_ig.png" /></figure><h4>Control-M Integration Plug-ins Used in This Architecture</h4><p>To orchestrate this multi-cloud analytics pipeline, we utilized Control-M’s native integration plug-ins to automate and govern key tasks across AWS and Google Cloud. These plug-ins enabled seamless execution of file transfers, SQL-based transformations, and dashboard refreshes, all from within a unified Control-M workflow.</p><p><a href="https://documents.bmc.com/supportu/9.0.21.300/en-US/Documentation/Managed_File_Transfer.htm"><strong>Control-M Managed File Transfer (Version 9.0.21.300)</strong></a></p><ul><li>Enables secure, policy-driven movement of data between AWS S3 and Google Cloud Storage.</li><li>Used in this pipeline to transfer the S&amp;P 500 dataset from Amazon S3 (where it was initially downloaded) into a Google Cloud Storage bucket for BigQuery ingestion.</li><li>Ensures cross-cloud data movement is automated, auditable, and resilient to failures.</li></ul><p><a href="https://documents.bmc.com/supportu/9.0.21.300/en-US/Documentation/GCP_BigQuery.htm"><strong>Control-M for GCP BigQuery (Version 9.0.21.300)</strong></a></p><ul><li>Executes SQL jobs and load operations in Google BigQuery.</li><li>Automate schema creation, raw data ingestion, feature engineering, and analytics queries for identifying top gainers, decliners, and most volatile stocks.</li><li>Provides centralized control and monitoring of all BigQuery processing steps.</li></ul><p><a href="https://documents.bmc.com/supportu/9.0.21.300/en-US/Documentation/Amazon_QuickSight.htm"><strong>Control-M for AWS QuickSight Version (9.0.20.200)</strong></a></p><ul><li>Triggers full dataset refreshes within AWS QuickSight dashboards.</li><li>Ensuring that newly processed insights (e.g., top gainers/decliners) are instantly reflected in business reports.</li><li>Automates visualization updates as part of the end-to-end pipeline execution.</li></ul><h3>Workflow Breakdown</h3><p>Workflow definition in Control-M</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kSEVGEnG8v7L-40lqVWzHg.png" /></figure><h4>Prerequisites:</h4><p>Before setting up the jobs in Control-M, ensure the required Control-M plug-ins (e.g., Managed File Transfer, BigQuery, etc.) are deployed in your environment. You’ll also need to create a connection profile for each plug-in so Control-M can authenticate and communicate with the respective services.</p><p><em>For step-by-step setup instructions, see the Control-M documentation:</em></p><p><a href="https://documents.bmc.com/supportu/9.0.21.300/en-US/Documentation/Integrations_Main.htm"><strong><em>Control-M Integrations</em></strong></a></p><p><strong><em>Note:</em></strong><em><br>All JSON definitions shown in this blog are snippets for illustration. They capture only the key parts of each job (e.g., Type, Src, Dest, FileTransfers, SQLStatement). The full JSON files, with complete scheduling logic, events, and metadata, are available on our GitHub repo </em><a href="https://github.com/controlm-samples/sp500-controlM-workflow"><em>here</em></a><em>.</em></p><h3>DATA INGESTION AND TRANSFORMATION</h3><blockquote><strong>Note:</strong> In the sections below, some steps show:</blockquote><blockquote><strong>SQL</strong> → the query we wrote in BigQuery</blockquote><blockquote><strong>JSON</strong> → the Control-M job definition automatically generated for orchestration</blockquote><h4>* BQ MFT Job s3-to-gcs</h4><p><strong>What it does: </strong><br> — Transfers the raw CSV file (all_stocks_5yr.csv) from an AWS S3 bucket to a Google Cloud Storage (GCS) bucket (sp500-etl). <br> — Serves as the cross-cloud bridge between AWS and GCP. <br> — This is the first step in the pipeline.</p><pre>{ <br><br>  &quot;Type&quot;: &quot;Job:FileTransfer&quot;, <br>  &quot;ConnectionProfileSrc&quot;: &quot;MFTS3&quot;, <br>  &quot;ConnectionProfileDest&quot;: &quot;joggcp&quot;, <br>  &quot;S3BucketNameSrc&quot;: &quot;gcp-bigquery-source&quot;, <br>  &quot;GCSBucketNameDest&quot;: &quot;sp500-etl&quot;, <br>  &quot;FileTransfers&quot;: [ <br>    { <br>      &quot;Src&quot;: &quot;/all_stocks_5yr.csv&quot;, <br>      &quot;Dest&quot;: &quot;/&quot;, <br>      &quot;TransferType&quot;: &quot;Binary&quot; <br>    } <br>  ] <br>}</pre><h4>* BQ Schema Table Creation</h4><p><strong>What it does:</strong> <br> — Creates or replaces the sp500_raw table in BigQuery. <br> — Defines the schema with columns like date, open, close, high, low, volume, and Name. <br> — Waits for the MFT job to finish transferring the data.</p><pre>CREATE OR REPLACE TABLE `sp500_dataset.sp500_raw` (<br>date DATE,<br>open FLOAT64,<br>high FLOAT64,<br>low FLOAT64,<br>close FLOAT64,<br>volume INT64,<br>Name STRING<br>);</pre><pre>{<br>  &quot;Type&quot;: &quot;Job:GCP BigQuery&quot;,<br>  &quot;ConnectionProfile&quot;: &quot;SP500-BIGQUERY&quot;,<br>  &quot;Action&quot;: &quot;Query&quot;,<br>  &quot;Src&quot;: &quot;File_Transfer_Job_2&quot;,<br>  &quot;Dest&quot;: &quot;BQ_Load_data_to_table&quot;,<br>  &quot;FileTransfers&quot;: [<br>    {<br>      &quot;Src&quot;: &quot;s3://gcp-bigquery-source/all_stocks_5yr.csv&quot;,<br>      &quot;Dest&quot;: &quot;sp500_dataset.sp500_raw&quot;,<br>      &quot;TransferType&quot;: &quot;BigQueryLoad&quot;<br>    }<br>  ],<br>  &quot;SQLStatement&quot;: &quot;CREATE OR REPLACE TABLE `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_raw` (date DATE, open FLOAT64, high FLOAT64, low FLOAT64, close FLOAT64, volume INT64, Name STRING);&quot;<br>}</pre><h4>* BQ Load data to table</h4><p><strong>What it does: </strong><br> — Loads the CSV file from the GCS bucket (gs://sp500-etl/all_stocks_5yr.csv) into the sp500_raw table. <br> — Performs schema-based loading with a maximum of 10 bad records allowed. <br> — Triggers the next transformation job upon success.</p><pre>{<br>  &quot;Type&quot;: &quot;Job:GCP BigQuery&quot;, <br>  &quot;Action&quot;: &quot;Load&quot;, <br>  &quot;Destination Table Properties&quot;: { <br>    &quot;tableId&quot;: &quot;sp500_raw&quot; <br>  }, <br>  &quot;Destination/Source Bucket URIs&quot;: &quot;gs://sp500-etl/all_stocks_5yr.csv&quot;, <br>  &quot;Load Options&quot;: &quot;\&quot;maxBadRecords\&quot;: 10&quot; <br>} </pre><h4>* BQ Clean Data</h4><p><strong>What it does: </strong><br> — Reads from sp500_raw and creates a new enriched table called sp500_clean. <br> — Adds calculated columns: daily_return, ma_7, ma_30, and volatility_7d. <br> — This table becomes the foundation for analytics queries and dashboarding.</p><pre>CREATE OR REPLACE TABLE sp500_dataset.sp500_clean AS<br>SELECT<br>DATE(date) AS date,<br>open, high, low, close, volume, Name,<br>SAFE_DIVIDE(close — open, open) AS daily_return,<br>AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma_7,<br>AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS ma_30,<br>STDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS volatility_7d<br>FROM sp500_dataset.sp500_raw<br>WHERE volume IS NOT NULL AND close IS NOT NULL;</pre><pre>{<br>  &quot;Type&quot;: &quot;Job:GCP BigQuery&quot;,<br>  &quot;ConnectionProfile&quot;: &quot;SP500-BIGQUERY&quot;,<br>  &quot;Action&quot;: &quot;Query&quot;,<br>  &quot;Src&quot;: &quot;BQ_Load_data_to_table&quot;,<br>  &quot;Dest&quot;: &quot;BQ_Clean_Data&quot;,<br>  &quot;FileTransfers&quot;: [<br>    {<br>      &quot;Src&quot;: &quot;sp500_dataset.sp500_raw&quot;,<br>      &quot;Dest&quot;: &quot;sp500_dataset.sp500_clean&quot;,<br>      &quot;TransferType&quot;: &quot;BigQueryTransform&quot;<br>    }<br>  ],<br>  &quot;SQLStatement&quot;: &quot;CREATE OR REPLACE TABLE `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_clean` AS SELECT DATE(date) AS date, open, high, low, close, volume, Name, SAFE_DIVIDE(close - open, open) AS daily_return, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma_7, AVG(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS ma_30, STDDEV(close) OVER (PARTITION BY Name ORDER BY DATE(date) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS volatility_7d FROM `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_raw`;&quot;<br>}</pre><h4>* AWS QuickSight Refresh</h4><p><strong>What it does: </strong><br> — Performs a full dataset refresh in AWS QuickSight using the dataset ID. <br> — Ensures dashboards are updated with the most recent data in sp500_clean. <br> — Triggers the analytics query jobs after completion.</p><pre>{<br>  &quot;Type&quot;: &quot;Job:AWS QuickSight&quot;, <br>  &quot;AWS Dataset ID”: “98012734-e8cc-49a7-b8b4–19592abe275e”,<br>  &quot;Refresh Type&quot;: &quot;Full Refresh&quot;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/362/1*1yRZrAAMDH80hOe_JXonqw.png" /><figcaption>Successful run of the initial workflow</figcaption></figure><h3><strong>ANALYSIS PIPELINES/QUERIES</strong></h3><h4>* BQ Top Daily Decliners</h4><p><strong>What it does: </strong><br> — Creates the top_daily_decliners table in BigQuery. <br> — Selects the 10 stocks with the largest negative return on 2018–02–07. <br> — Used to identify worst-performing stocks.</p><p>####SQL Query</p><pre>CREATE OR REPLACE TABLE sp500_dataset.top_daily_decliners AS<br>SELECT Name, date,<br>ROUND(((close — open) / open) * 100, 2) AS percent_change<br>FROM sp500_dataset.sp500_clean<br>WHERE date = ‘2018–02–07’<br>ORDER BY percent_change ASC<br>LIMIT 10;</pre><pre>{<br>  &quot;Type&quot;: &quot;Job:GCP BigQuery&quot;,<br>  &quot;ConnectionProfile&quot;: &quot;SP500-BIGQUERY&quot;,<br>  &quot;Action&quot;: &quot;Query&quot;,<br>  &quot;Src&quot;: &quot;sp500_dataset.sp500_clean&quot;,<br>  &quot;Dest&quot;: &quot;sp500_dataset.top_daily_decliners&quot;,<br>  &quot;FileTransfers&quot;: [<br>    {<br>      &quot;Src&quot;: &quot;sp500_dataset.sp500_clean&quot;,<br>      &quot;Dest&quot;: &quot;sp500_dataset.top_daily_decliners&quot;,<br>      &quot;TransferType&quot;: &quot;BigQueryTransform&quot;<br>    }<br>  ],<br>  &quot;SQLStatement&quot;: &quot;CREATE OR REPLACE TABLE `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.top_daily_decliners` AS SELECT Name, date, ROUND(((close - open) / open) * 100, 2) AS percent_change FROM `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_clean` WHERE date = &#39;2018-02-07&#39; ORDER BY percent_change ASC LIMIT 10;&quot;<br>}</pre><h4>* BQ Top Daily Gainers</h4><p><strong>What it does: </strong><br> — Creates the top_daily_gainers table. <br> — Selects the 10 stocks with the highest percentage return on 2018–02–07. <br> — Used for bullish market analysis.</p><pre>CREATE OR REPLACE TABLE sp500_dataset.top_daily_gainers AS<br>SELECT Name, date,<br>ROUND(((close — open) / open) * 100, 2) AS percent_change<br>FROM sp500_dataset.sp500_clean<br>WHERE date = ‘2018–02–07’<br>ORDER BY percent_change DESC<br>LIMIT 10;</pre><pre>{<br>  &quot;Type&quot;: &quot;Job:GCP BigQuery&quot;,<br>  &quot;ConnectionProfile&quot;: &quot;SP500-BIGQUERY&quot;,<br>  &quot;Action&quot;: &quot;Query&quot;,<br>  &quot;Src&quot;: &quot;sp500_dataset.sp500_clean&quot;,<br>  &quot;Dest&quot;: &quot;sp500_dataset.top_daily_gainers&quot;,<br>  &quot;FileTransfers&quot;: [<br>    {<br>      &quot;Src&quot;: &quot;sp500_dataset.sp500_clean&quot;,<br>      &quot;Dest&quot;: &quot;sp500_dataset.top_daily_gainers&quot;,<br>      &quot;TransferType&quot;: &quot;BigQueryTransform&quot;<br>    }<br>  ],<br>  &quot;SQLStatement&quot;: &quot;CREATE OR REPLACE TABLE `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.top_daily_gainers` AS SELECT Name, date, ROUND(((close - open) / open) * 100, 2) AS percent_change FROM `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_clean` WHERE date = &#39;2018-02-07&#39; ORDER BY percent_change DESC LIMIT 10;&quot;<br>}</pre><h4>* BQ Top Most Volatile</h4><p><strong>What it does: </strong><br> — Creates the top_daily_volatile table. <br> — Calculates volatility as (high — low) / open * 100. <br> — Highlights top 10 most volatile stocks for trading insights</p><pre>CREATE OR REPLACE TABLE sp500_dataset.top_daily_volatile AS<br>SELECT Name, date,<br>ROUND(((high — low) / open) * 100, 2) AS intraday_volatility<br>FROM sp500_dataset.sp500_clean<br>WHERE date = ‘2018–02–07’<br>ORDER BY intraday_volatility DESC<br>LIMIT 10;</pre><pre>{<br>  &quot;Type&quot;: &quot;Job:GCP BigQuery&quot;,<br>  &quot;ConnectionProfile&quot;: &quot;SP500-BIGQUERY&quot;,<br>  &quot;Action&quot;: &quot;Query&quot;,<br>  &quot;Src&quot;: &quot;sp500_dataset.sp500_clean&quot;,<br>  &quot;Dest&quot;: &quot;sp500_dataset.top_daily_volatile&quot;,<br>  &quot;FileTransfers&quot;: [<br>    {<br>      &quot;Src&quot;: &quot;sp500_dataset.sp500_clean&quot;,<br>      &quot;Dest&quot;: &quot;sp500_dataset.top_daily_volatile&quot;,<br>      &quot;TransferType&quot;: &quot;BigQueryTransform&quot;<br>    }<br>  ],<br>  &quot;SQLStatement&quot;: &quot;CREATE OR REPLACE TABLE `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.top_daily_volatile` AS SELECT Name, date, ROUND(((high - low) / open) * 100, 2) AS intraday_volatility FROM `sso-gcp-dba-ctm4-pub-cc10274.sp500_dataset.sp500_clean` WHERE date = &#39;2018-02-07&#39; ORDER BY intraday_volatility DESC LIMIT 10;&quot;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YYbJokMIj-LiWLo0vWP7jA.png" /><figcaption>Successful run of the Analysis queries workflow</figcaption></figure><h3>Business Outcome</h3><p>After building and cleaning our S&amp;P 500 dataset in BigQuery, we connected it to Amazon QuickSight to create an interactive dashboard. The goal was to move from raw stock price data to meaningful financial insights that investors, analysts, or decision-makers could act on.</p><p>This dashboard combines both long-term market trends and short-term performance snapshots, allowing us to see how individual companies perform daily while also understanding the broader risk-reward dynamics of the S&amp;P 500.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e2TIfw61xFRfTJmP79duvw.png" /></figure><p>Below, we’ll walk through each visualization, explaining what we built, how we built it, and what story the data tells.</p><h4>Closing Price Over Time (Line Chart):</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QMpTlBrhInFx8aT8q-9PVQ.png" /></figure><p><strong>What we did:</strong> Took cleaned daily stock prices (sp500_clean) and plotted the average closing price for selected companies across quarterly time intervals.</p><p><strong>What it shows:</strong> A trend line of how major tech companies (AAPL, AMZN, FB, GOOG, MSFT, NFLX) have grown in market value over several years. It highlights long-term growth patterns and market leaders.</p><h4>Top 20 Daily Gainers (Bar Chart)</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0ztmynYe7uNITrLL88n7AQ.png" /></figure><p><strong>What we did:</strong> Ran a query to calculate percent change = (close — open) / open for each stock on a given day and ranked them in descending order.</p><p><strong>What it shows: </strong>The 20 companies with the highest daily returns (best performers). This gives investors a quick glance at momentum stocks for that day.</p><h4>Top 20 Daily Decliners (Bar Chart)</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*02jlNgmHhLMMEp8x8jpY9Q.png" /></figure><p><strong>What we did:</strong> Used the same percent change formula but sorted in ascending order.</p><p><strong>What it shows: </strong>The 20 worst-performing companies on the same day, i.e., the biggest daily losers. This is critical for spotting declining or risky investments.</p><h4>Daily Return vs Volatility (Scatter Plot — Risk/Reward Map)</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ncIaoNWPNjnJSOs3kLQ3iA.png" /></figure><p><strong>What we did:</strong> Calculated daily returns and an intraday volatility metric = (high — low) / open for each stock. Then plotted return (x-axis) against volatility (y-axis).</p><p><strong>What it shows:</strong> A risk-reward map of the S&amp;P 500. Each dot is a stock, showing if high returns are associated with high volatility. Investors use this to balance growth potential vs. stability.</p><h4>All together:</h4><ul><li>The line chart → long-term growth view.</li><li>The gainers/decliners → short-term performance snapshot.</li><li>The scatter plot → risk vs reward tradeoff.</li></ul><p>This shows us both daily insights and long-term trends, a very real-world financial analysis workflow.</p><h3>Benefits of Using Control-M for S&amp;P 500 ETL Orchestration</h3><p>In a multi-cloud, data-intensive environment like the one used for this S&amp;P 500 analytics pipeline, achieving reliable orchestration is critical. Control-M serves as the enterprise-grade backbone that brings all components — file transfer, data warehousing, transformation, and visualization — into a unified, governed, and traceable flow.</p><p>Rather than building and managing custom scripts or multiple schedulers to coordinate each component across AWS and Google Cloud, Control-M offers an out-of-the-box, low-code solution that ensures operational stability, clear dependencies, and visibility from end to end.</p><p>Here are the key benefits observed in this implementation:</p><h4>1. End-to-End Orchestration Across Cloud Platforms</h4><p>Control-M enables seamless orchestration across AWS (S3, QuickSight) and Google Cloud (GCS, BigQuery) without needing to manage multiple schedulers or cloud-specific workflows. This allows the data engineering team to work within a single framework for development, scheduling, execution, and monitoring.</p><ul><li>Unified management of S3, GCS, BigQuery, and QuickSight pipelines.</li><li>Avoids building custom integration logic or maintaining third-party tools.</li><li>Simplifies DevOps and deployment pipelines by consolidating control</li></ul><h4>2. Event-Driven Workflow Automation</h4><p>This pipeline relies heavily on event-based execution — each job begins only when its prerequisite completes successfully. Control-M makes this straightforward using native event-handling features like eventsToAdd, eventsToWaitFor, and eventsToDelete.</p><ul><li>Prevents downstream jobs from running if upstream logic fails.</li><li>Ensures data quality and consistency before analysis.</li><li>Reduces manual oversight by enforcing conditional execution logic.</li></ul><h4>3. Robust Scheduling and Calendar Logic</h4><p>Control-M supports sophisticated scheduling strategies beyond simple cron expressions. For example, this pipeline uses a custom EVERYDAY rule-based calendar, which can easily be adapted to exclude weekends, public holidays, or non-trading days without altering job logic.</p><ul><li>Aligns job execution with financial market hours or business calendars.</li><li>Enables SLA enforcement and rescheduling policies.</li><li>Reduces risk of missed or misaligned job runs.</li></ul><h4>4. Monitoring, Logging, and SLA Management</h4><p>With Control-M, operators have real-time visibility into the status of each job, including start time, end time, duration, logs, return codes, and more. This monitoring domain becomes the command center for both support and data teams.</p><ul><li>Centralized dashboards for job health and trend analysis.</li><li>Quick root cause diagnosis via access to historical logs.</li><li>Built-in alerts and SLA breach notifications.</li></ul><h4>5. Governance, Compliance, and Audit Readiness</h4><p>Control-M inherently tracks all job executions, parameters, changes, and outcomes, providing a strong audit trail that meets enterprise and regulatory compliance needs. In finance and capital markets, this is a major advantage.</p><ul><li>Detailed historical records of job executions and dependencies.</li><li>Full traceability of data movement and transformations.</li><li>Supports internal governance, external audits, and SOC 2/ISO compliance reviews.</li></ul><h4>6. Scalability and Maintainability</h4><p>The Control-M workflow can scale as data volume grows or when more datasets are added. Adding new KPIs, features, or parallel workflows (e.g., new stock indices) can be achieved with minimal overhead.</p><ul><li>Modular folder/job structure makes workflows reusable.</li><li>Easily accommodates additional job types (e.g., ML model training, alerting).</li><li>Supports dynamic parameterization for flexible environments (dev/test/prod).</li></ul><h4>7. Low-Code Development for Faster Deployment</h4><p>Jobs such as BigQuery queries, file transfers, and QuickSight refreshes are created using Control-M’s intuitive UI or JSON definitions. Developers don’t need to write extensive shell scripts or pipelines reducing complexity and time-to-deploy.</p><ul><li>Reduces onboarding time for new engineers.</li><li>Encourages collaboration between data engineering and operations teams.</li><li>Minimizes custom code and maintenance burden.</li></ul><h4>8. Error Handling and Recovery</h4><p>Control-M’s built-in error handling mechanisms — such as automatic retries, job hold logic, and event-driven branching — reduce manual intervention in the case of transient or systemic failures.</p><ul><li>Supports conditional logic for graceful degradation.</li><li>Allow jobs to retry intelligently or notify stakeholders upon failure.</li><li>Enhances system resilience and reliability.</li></ul><h4>Summary of Control-M Benefits in this Use Case</h4><ul><li>Orchestration across AWS and GCP from one tool.</li><li>Event-driven architecture with strong dependency management.</li><li>Flexible, rule-based scheduling for financial workflows.</li><li>Centralized monitoring and alerting for all job states.</li><li>Full audit trail for governance and compliance.</li><li>Scalable architecture for future datasets and ML use cases.</li><li>Low-code development accelerates delivery and reduces technical debt.</li><li>Resilient error handling ensures continuity in production.</li></ul><h3>Conclusion</h3><p>This blog demonstrates the full lifecycle of turning raw financial data into actionable insights. Using Control-M, we automated the ETL workflow: moving files from S3 to GCS, cleaning and transforming the data in BigQuery, and refreshing datasets in Amazon QuickSight. The dashboard then provides a live analytical layer, showcasing both market-wide trends (like long-term price growth) and daily market signals (such as top gainers, decliners, and volatility).</p><p>By integrating orchestration, cloud data warehousing, and visualization, we built a pipeline that not only processes large-scale stock data but also keeps insights fresh and relevant for decision-making. This same approach can be extended to other financial datasets or even different industries, making it a reusable framework for data-driven analysis at scale.</p><h4>Want to run this yourself?</h4><p>This isn’t a demo video — it’s a real, hands-on lab.</p><p>Click below to launch the S&amp;P 500 interactive environment!</p><figure><a href="https://play.instruqt.com/embed/bmc/invite/ghh4jqsnnqo3"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u_ANzxVuIacqnl01oK-oSw.png" /></a></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4f68e27f3f1c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/operationalizing-s-p-500-analytics-with-control-m-bigquery-and-amazon-quicksight-4f68e27f3f1c">Operationalizing S&amp;P 500 Analytics with Control-M, BigQuery, and Amazon QuickSight</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Orchestrating Snowflake with Control-M]]></title>
            <link>https://medium.com/bmc-digital-it/orchestrating-snowflake-with-control-m-558185b7d321?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/558185b7d321</guid>
            <category><![CDATA[data-orchestration]]></category>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[control-m]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Tue, 26 Aug 2025 16:15:05 GMT</pubDate>
            <atom:updated>2026-04-03T20:12:07.310Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8Iz-I42LRGG49Y-I2FYnjg.png" /></figure><p>By: <a href="https://www.linkedin.com/in/samuelduru/">Sam Duru-Nnebue</a></p><p><a href="https://www.snowflake.com/">Snowflake</a> is one of the most commonly used data warehouses, and orchestrating Snowflake queries as part of a data pipeline is a very common use case in Apache Airflow. Snowflake activities requiring orchestration are usually part of a larger data pipeline that involves ingestion, transformation, and reverse ETL activities. However, in this blog we are zooming into one part of the data pipeline: orchestrating Snowflake with Control-M orchestrating the following activities.</p><ul><li>Create a table.</li><li>Load the data.</li><li>Run transformations on the data.</li><li>Aggregate the data.</li><li>Run data queries.</li></ul><p>For this blog, we will use a <a href="https://www.kaggle.com/datasets/dianaddx/aircraft-wildlife-strikes-1990-2023?select=STRIKE_REPORTS.csv">sample dataset available on Kaggle</a>. This dataset contains detailed records of airplane wildlife strike incidents from 1990 to 2023, involving military, commercial, or civil aircraft, as reported in the FAA Wildlife Strike Database. It covers just the first 100 columns of the dataset. It includes incident dates, affected airports, aircraft details, wildlife species, locations, flight phases, damage levels, and weather conditions at the time of each incident.</p><p>Included below is the flow of the orchestrated pattern:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cOEh3T-2bKX4XCQ0CXS1zw.png" /></figure><p><strong>Pre-requisites</strong></p><p>To get the most out of this tutorial, you will need:</p><ul><li>To understand Snowflake basics. Here’s an <a href="https://docs.snowflake.com/en/user-guide-intro.html">Introduction to Snowflake</a> to help get you started.</li><li>Have a Snowflake account.</li><li>Have access to Control M <a href="https://controlm.github.io/">Automation API</a>.</li><li>Understand SQL basics. See this <a href="https://www.w3schools.com/sql/">W3 SQL tutorial</a> for background information.</li><li>Have an AWS Account.</li></ul><p><strong>Create a security integration (Snowflake Oauth)</strong></p><p>This operation initiates or updates a Snowflake OAuth security integration within the account, enabling OAuth-supporting clients to direct users to an authorization page. This step is crucial for generating access tokens, and potentially refresh tokens, facilitating secured access to Snowflake. For more details, visit this Snowflake <a href="https://docs.snowflake.com/en/sql-reference/sql/create-security-integration-oauth-snowflake">OAUTH Setup</a>.</p><p>To begin, create a Snowflake <a href="https://docs.snowflake.com/en/sql-reference/sql/create-database">database</a>, <a href="https://docs.snowflake.com/en/sql-reference/sql/create-schema">schema</a>, <a href="https://docs.snowflake.com/en/sql-reference/sql/create-role">role</a>, stage* and <a href="https://docs.snowflake.com/en/sql-reference/sql/create-warehouse">warehouse</a>.</p><p><em>*Snowflake stages are locations where data files are stored (staged) for loading and unloading data. See a screenshot of a Snowflake stage that attaches the S3 bucket to the Snowflake profile below.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YE-M2VN8U44sB2GN-6IpMQ.png" /></figure><p>Next we will begin with setting up a connection profile in Control-M for Snowflake and then create a workflow of jobs that will orchestrate a number of activities in Snowflake.</p><p><strong>Configure a Snowflake connection</strong><a href="https://docs.astronomer.io/learn/airflow-snowflake#step-2-configure-a-snowflake-connection"><strong>​</strong></a></p><ol><li>In Control-M, go to Control-M Applications &gt; Configuration &gt; Quick Actions &gt; Manage Centralized Connection Profile &gt; Add Connection Profile and select Snowflake.</li><li>Enter the following information:</li></ol><ul><li><strong>Connection Profile Name:</strong> <em>snowflake_test</em></li><li><strong>Description:</strong> <em>(optional — can include an overview of what the profile will be doing)</em></li><li><strong>Account Identifier: </strong><a href="https://docs.snowflake.com/en/user-guide/admin-account-identifier#account-identifiers">Detailed here</a> (generated based on Snowflake account creation details)</li><li><strong>Region:</strong> <em>Your Snowflake region (example: us-east-1)</em></li><li><strong>Client ID:</strong> <em>(generated from the OAuth setup above)</em></li><li><strong>Client Secret:</strong> <em>(generated from the OAuth setup above)</em></li><li><strong>Refresh Token:</strong> <em>(generated from OAuth setup above — make sure this value is </em><a href="https://www.urlencoder.org/"><em>url-encoded</em></a><em>)</em></li><li><strong>Redirect URL:</strong> <em>(generated from OAuth setup above — make sure this value is </em><a href="https://www.urlencoder.org/"><em>url-encoded</em></a><em>)</em></li></ul><p>Your connection should look something like the screenshot below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/542/1*KPks4dy260SrLUPZ0bC4kQ.png" /></figure><p>This use case is designed to walk you through creating various jobs in Control-M, tailored for diverse operational needs. It includes job types like file transfers, SQL statements in Snowflake, Snowflake-stored procedures, and SQL files for Snowflake within Control M.</p><p><strong>Create a workspace</strong></p><p>In Control-M, go to Planning, click on the dropdown next to Home and select Add New Workspace. Name the workspace, give a description of what would be in it, select your server and folder, and click on Create.</p><p>This workspace serves as a container for your jobs and workflows. After a workspace is created, it automatically creates a folder for you, which is where you can start creating your jobs. See an example below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/504/1*2MWRAXf-5IFYeIKO1-rEaw.png" /></figure><p><strong>Creating a file transfer job (S3_Object_Transfer)</strong></p><p>To create a file transfer job, enter the following details:</p><ul><li><strong>Type:</strong> Job:FileTransfer</li><li><strong>Description:</strong> Transfers the CSV file from a public-facing S3 bucket to the S3 bucket attached to the Snowflake stage.</li><li><strong>Key Operations:</strong> Source to Destination: Transfers /TestCSV2.csv from source to/snowflake/folder in destination.</li></ul><p>See an example in the figure below:</p><pre>&quot;S3_Object_Transfer&quot;: {<br>  &quot;Type&quot;: &quot;Job:FileTransfer&quot;,<br>  &quot;ConnectionProfileSrc&quot;: &quot;MFTS3&quot;,<br>  &quot;ConnectionProfileDest&quot;: &quot;MFTS3&quot;,<br>  &quot;S3BucketNameSrc&quot;: &quot;INSERT_SOURCE_BUCKET_NAME&quot;,<br>  &quot;S3BucketNameDest&quot;: &quot; INSERT_DESTINATION_BUCKET_NAME &quot;,<br>  &quot;Host&quot;: &quot;INSERT_HOSTNAME&quot;,<br>  &quot;CreatedBy&quot;: &quot;CREATOR_EMAIL_AUTOMATICALLY_GENERATED&quot;,<br>  &quot;Description&quot;: &quot;Transfer CSV from s3 bucket to Snowflake stage&quot;,<br>  &quot;RunAs&quot;: &quot;MFTS3+MFTS3&quot;,<br>  &quot;Variables&quot;: [<br>    {&quot;FTP-LOSTYPE&quot;: &quot;Unix&quot;},<br>    {&quot;FTP-CONNTYPE1&quot;: &quot;S3&quot;},<br>    {&quot;FTP-ROSTYPE&quot;: &quot;Unix&quot;},<br>    {&quot;FTP-CONNTYPE2&quot;: &quot;S3&quot;},<br>    {&quot;FTP-CM_VER&quot;: &quot;9.0.00&quot;}<br>  ],<br>  &quot;FileTransfers&quot;: [<br>    {<br>      &quot;TransferType&quot;: &quot;Binary&quot;,<br>      &quot;TransferOption&quot;: &quot;SrcToDestFileWatcher&quot;,<br>      &quot;Src&quot;: &quot;/TestCSV2.csv&quot;,<br>      &quot;Dest&quot;: &quot;/snowflake/&quot;,<br>      &quot;ABSTIME&quot;: &quot;0&quot;,<br>      &quot;TIMELIMIT&quot;: &quot;0&quot;,<br>      &quot;UNIQUE&quot;: &quot;0&quot;,<br>      &quot;SRCOPT&quot;: &quot;0&quot;,<br>      &quot;IF_EXIST&quot;: &quot;0&quot;,<br>      &quot;DSTOPT&quot;: &quot;0&quot;,<br>      &quot;RECURSIVE&quot;: &quot;0&quot;,<br>      &quot;EXCLUDE_WILDCARD&quot;: &quot;0&quot;,<br>      &quot;TRIM&quot;: &quot;1&quot;,<br>      &quot;NULLFLDS&quot;: &quot;0&quot;,<br>      &quot;VERNUM&quot;: &quot;0&quot;,<br>      &quot;CASEIFS&quot;: &quot;0&quot;,<br>      &quot;FileWatcherOptions&quot;: {<br>        &quot;UnitsOfTimeLimit&quot;: &quot;Minutes&quot;<br>      },<br>      &quot;IncrementalTransfer&quot;: {<br>        &quot;IncrementalTransferEnabled&quot;: false,<br>        &quot;MaxModificationAgeForFirstRunEnabled&quot;: false,<br>        &quot;MaxModificationAgeForFirstRunInHours&quot;: &quot;1&quot;<br>      }<br>    }<br>  ],<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;S3_Object_Transfer-TO-CREATE_TABLE&quot;}]<br>  }<br>}</pre><p><strong>Creating a Snowflake SQL statement job (CREATE_TABLE)</strong></p><p>To create this job, enter the details below. Note, the Control-M Snowflake plugin utilizes the Snowflake SQL API to connect to Snowflake. When submitting multiple SQL statements, the API requires statements to be concatenated and setting the MULTI_STATEMENT_COUNT parameter. Please see this <a href="https://docs.snowflake.com/en/developer-guide/sql-api/submitting-multiple-statements">Snowflake API</a> documentation for more details.</p><ul><li><strong>Type:</strong> Job:Snowflake</li><li><strong>Action:</strong> Creates or replaces a table (CSV_TBL) in Snowflake using a template that infers schema from the specified CSV file, allowing dynamic schema creation based on file content.</li><li><strong>Description:</strong> This job dynamically creates a table structure based on the CSV file’s schema.</li><li><strong>Dependencies:</strong> Waits for the event S3_Object_Transfer-TO-CREATE_TABLE, ensuring the file transfer is completed before attempting to create the table.</li></ul><p>See an example in the figure below:</p><pre>&quot;CREATE_TABLE&quot;: {<br>  &quot;Type&quot;: &quot;Job:Snowflake&quot;,<br>  &quot;ConnectionProfile&quot;: &quot;INSERT_CONNECTION_PROFILE_NAME&quot;,<br>  &quot;Action&quot;: &quot;SQL Statement&quot;,<br>  &quot;Add Condition&quot;: &quot;unchecked&quot;,<br>  &quot;Activity Options&quot;: &quot;Copy From External Datasource&quot;,<br>  &quot;Overwrite&quot;: &quot;Yes&quot;,<br>  &quot;Start or Pause Snowpipe&quot;: &quot;Pause Snowpipe&quot;,<br>  &quot;Show More Options&quot;: &quot;checked&quot;,<br>  &quot;Show Output&quot;: &quot;checked&quot;,<br>  &quot;Database&quot;: &quot;INSERT_DATABASE_NAME&quot;,<br>  &quot;Schema&quot;: &quot; INSERT_SCHEMA_NAME &quot;,<br>  &quot;Snowflake SQL Statement&quot;: <br>    &quot;CREATE OR REPLACE TABLE CSV_TBL USING TEMPLATE (&quot; + <br>    &quot;SELECT ARRAY_AGG(OBJECT_CONSTRUCT(*)) WITHIN GROUP (&quot; + <br>    &quot;ORDER BY ORDER_ID) FROM TABLE (INFER_SCHEMA(&quot; + <br>    &quot;LOCATION=&gt;&#39;@airportdata/TestCSV2.csv&#39;, &quot; + <br>    &quot;FILE_FORMAT=&gt;&#39;csv_format_0&#39;)));&quot;,<br>  &quot;Statement Timeout&quot;: &quot;10&quot;,<br>  &quot;Role&quot;: &quot;SYSADMIN&quot;,<br>  &quot;Warehouse&quot;: &quot;INSERT_SNOWFLAKE_WAREHOUSE&quot;,<br>  &quot;Host&quot;: &quot;INSERT_HOSTNAME&quot;,<br>  &quot;CreatedBy&quot;: &quot;CREATOR_EMAIL_AUTOMATICALLY_GENERATED&quot;,<br>  &quot;RunAs&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME &quot;,<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;S3_Object_Transfer-TO-CREATE_TABLE&quot;}]<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;CREATE_TABLE-TO-COPY_INTO_TABLE&quot;}]<br>  },<br>  &quot;eventsToDelete&quot;: {<br>    &quot;Type&quot;: &quot;DeleteEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;S3_Object_Transfer-TO-CREATE_TABLE&quot;}]<br>  }<br>}</pre><p><strong>Creating a Snowflake SQL statement job (COPY_INTO_TABLE)</strong></p><p>To create this job, enter the following details:</p><ul><li><strong>Type:</strong> Job:Snowflake</li><li><strong>Action:</strong> Executes an SQL statement to load data into a table (CSV_TBL) from a staged file (@airportdata/TestCSV2.csv) with specific file format settings.</li><li><strong>Description:</strong> This job loads data into Snowflake using the COPY command, preparing the data for further analysis or processing. It waits for an event indicating readiness to proceed, ensuring proper sequence in data workflow.</li><li><strong>Dependencies:</strong> Waits for the event CREATE_TABLE-TO-COPY_INTO_TABLE before execution.</li></ul><p>See an example in the figure below:</p><pre>&quot;COPY_INTO_TABLE&quot;: {<br>  &quot;Type&quot;: &quot;Job:Snowflake&quot;,<br>  &quot;ConnectionProfile&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME &quot;,<br>  &quot;Action&quot;: &quot;SQL Statement&quot;,<br>  &quot;Add Condition&quot;: &quot;unchecked&quot;,<br>  &quot;Activity Options&quot;: &quot;Copy From External Datasource&quot;,<br>  &quot;Overwrite&quot;: &quot;Yes&quot;,<br>  &quot;Start or Pause Snowpipe&quot;: &quot;Pause Snowpipe&quot;,<br>  &quot;Show More Options&quot;: &quot;checked&quot;,<br>  &quot;Show Output&quot;: &quot;checked&quot;,<br>  &quot;Database&quot;: &quot; INSERT_DATABASE_NAME &quot;,<br>  &quot;Schema&quot;: &quot;INSERT_SCHEMA_NAME&quot;,<br>  &quot;Snowflake SQL Statement&quot;: <br>    &quot;COPY INTO csv_tbl FROM @airportdata/TestCSV2.csv &quot; + <br>    &quot;FILE_FORMAT = (skip_header = 1);%4E&quot;,<br>  &quot;Statement Timeout&quot;: &quot;10&quot;,<br>  &quot;Role&quot;: &quot;SYSADMIN&quot;,<br>  &quot;Warehouse&quot;: &quot;INSERT_SNOWFLAKE_WAREHOUSE &quot;,<br>  &quot;Host&quot;: &quot; INSERT_HOSTNAME &quot;,<br>  &quot;CreatedBy&quot;: &quot; CREATOR_EMAIL_AUTOMATICALLY_GENERATED &quot;,<br>  &quot;RunAs&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME &quot;,<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;CREATE_TABLE-TO-COPY_INTO_TABLE&quot;}]<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;COPY_INTO_TABLE-TO-QUERY_DATA&quot;}]<br>  },<br>  &quot;eventsToDelete&quot;: {<br>    &quot;Type&quot;: &quot;DeleteEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;CREATE_TABLE-TO-COPY_INTO_TABLE&quot;}]<br>  }<br>}</pre><p><strong>Creating a Snowflake SQL statement job (QUERY_DATA)</strong></p><p>To create this job, enter the following details:</p><ul><li><strong>Type:</strong> Job:Snowflake</li><li><strong>Action:</strong> Executes an SQL query to list the top 10 airports by incident count.</li><li><strong>Description:</strong> This job simplifies data review by aggregating incident data at high-traffic airports, offering a prioritized view of locations for focused analysis from a table called “<em>TESTTABLE2”</em>.</li><li><strong>Dependencies:</strong> Waits for COPY_INTO_TABLE-TO-QUERY_DATA, ensuring data is loaded and ready for querying.</li></ul><p>See an example in the figure below:</p><pre>&quot;QUERY_DATA&quot;: {<br>  &quot;Type&quot;: &quot;Job:Snowflake&quot;,<br>  &quot;ConnectionProfile&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME &quot;,<br>  &quot;Action&quot;: &quot;SQL Statement&quot;,<br>  &quot;Add Condition&quot;: &quot;unchecked&quot;,<br>  &quot;Activity Options&quot;: &quot;Copy From External Datasource&quot;,<br>  &quot;Overwrite&quot;: &quot;Yes&quot;,<br>  &quot;Start or Pause Snowpipe&quot;: &quot;Pause Snowpipe&quot;,<br>  &quot;Show More Options&quot;: &quot;checked&quot;,<br>  &quot;Show Output&quot;: &quot;checked&quot;,<br>  &quot;Database&quot;: &quot; INSERT_DATABASE_NAME &quot;,<br>  &quot;Schema&quot;: &quot; INSERT_SCHEMA_NAME &quot;,<br>  &quot;Snowflake SQL Statement&quot;: <br>    &quot;SELECT AIRPORT, COUNT(*) AS Total_Incidents &quot; + <br>    &quot;FROM TESTTABLE2 &quot; + <br>    &quot;GROUP BY AIRPORT &quot; + <br>    &quot;ORDER BY Total_Incidents DESC &quot; + <br>    &quot;LIMIT 10;&quot;,<br>  &quot;Warehouse&quot;: &quot; INSERT_SNOWFLAKE_WAREHOUSE &quot;,<br>  &quot;Role&quot;: &quot;SYSADMIN&quot;,<br>  &quot;Statement Timeout&quot;: &quot;10&quot;,<br>  &quot;Host&quot;: &quot; INSERT_HOSTNAME &quot;,<br>  &quot;CreatedBy&quot;: &quot; CREATOR_EMAIL_AUTOMATICALLY_GENERATED &quot;,<br>  &quot;Description&quot;: <br>    &quot;This query lists the top 10 airports with the highest number of incidents.&quot;,<br>  &quot;RunAs&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME &quot;,<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;COPY_INTO_TABLE-TO-QUERY_DATA&quot;}]<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;lochiamocosiQUERY_DATA-TO-UPDATE_DATA&quot;}]<br>  },<br>  &quot;eventsToDelete&quot;: {<br>    &quot;Type&quot;: &quot;DeleteEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;COPY_INTO_TABLE-TO-QUERY_DATA&quot;}]<br>  }<br>}</pre><p><strong>Creating a Snowflake SQL statement job (UPDATE_DATA)</strong></p><p>To create this job, enter the following details:</p><ul><li><strong>Type:</strong> Job:Snowflake</li><li><strong>Action:</strong> Updates records in the table, setting TIME_OF_DAY to ‘NA’ where it is “null” or “unknown”.</li><li><strong>Description:</strong> This job ensures data consistency for analysis by cleaning up incomplete time-of-day records in a table called “<em>TESTTABLE2”</em>.</li><li><strong>Dependencies:</strong> Waits for QUERY_DATA-TO-UPDATE_DATA, maintaining the sequence in data processing.</li></ul><p>See an example in the figure below:</p><pre>&quot;UPDATE_DATA&quot;: {<br>  &quot;Type&quot;: &quot;Job:Snowflake&quot;,<br>  &quot;ConnectionProfile&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME &quot;,<br>  &quot;Database&quot;: &quot; INSERT_DATABASE_NAME &quot;,<br>  &quot;Schema&quot;: &quot; INSERT_SCHEMA_NAME &quot;,<br>  &quot;Action&quot;: &quot;SQL Statement&quot;,<br>  &quot;Snowflake SQL Statement&quot;: <br>    &quot;UPDATE TESTTABLE2 SET TIME_OF_DAY = &#39;NA&#39; &quot; + <br>    &quot;WHERE TIME_OF_DAY IS NULL OR TIME_OF_DAY = &#39;Unknown&#39;;&quot;,<br>  &quot;Add Condition&quot;: &quot;unchecked&quot;,<br>  &quot;Activity Options&quot;: &quot;Copy From External Datasource&quot;,<br>  &quot;Overwrite&quot;: &quot;Yes&quot;,<br>  &quot;Start or Pause Snowpipe&quot;: &quot;Pause Snowpipe&quot;,<br>  &quot;Statement Timeout&quot;: &quot;10&quot;,<br>  &quot;Show More Options&quot;: &quot;checked&quot;,<br>  &quot;Role&quot;: &quot;SYSADMIN&quot;,<br>  &quot;Warehouse&quot;: &quot; INSERT_SNOWFLAKE_WAREHOUSE &quot;,<br>  &quot;Show Output&quot;: &quot;checked&quot;,<br>  &quot;Host&quot;: &quot; INSERT_HOSTNAME &quot;,<br>  &quot;CreatedBy&quot;: &quot; CREATOR_EMAIL_AUTOMATICALLY_GENERATED &quot;,<br>  &quot;Description&quot;: <br>    &quot;This statement sets the TIME_OF_DAY to &#39;NA&#39; for all records &quot; + <br>    &quot;where TIME_OF_DAY is currently null or Unknown&quot;,<br>  &quot;RunAs&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME &quot;,<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;lochiamocosiQUERY_DATA-TO-UPDATE_DATA&quot;}]<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;lochiamocosiUPDATE_DATA-TO-Query_for_a_specific_year&quot;}]<br>  },<br>  &quot;eventsToDelete&quot;: {<br>    &quot;Type&quot;: &quot;DeleteEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;lochiamocosiQUERY_DATA-TO-UPDATE_DATA&quot;}]<br>  }<br>}</pre><p><strong>Creating a Snowflake SQL statement job (Query_for_a_specific_year)</strong></p><p>To create this job, enter the following details:</p><ul><li><strong>Type:</strong> Job:Snowflake</li><li><strong>Action:</strong> Executes an SQL query to fetch incident details for a specific year (1994), ordered by month and date.</li><li><strong>Description:</strong> This job provides a temporal analysis of incidents, focusing on a specific year for detailed historical insight in a table called “<em>TESTTABLE2”</em>.</li><li><strong>Dependencies:</strong> Waits for UPDATE_DATA-TO-Query_for_a_specific_year, ensuring data is up-to-date for accuracy.</li></ul><p>See an example in the figure below:</p><pre>&quot;Query_for_a_specific_year&quot;: {<br>  &quot;Type&quot;: &quot;Job:Snowflake&quot;,<br>  &quot;ConnectionProfile&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME&quot;,<br>  &quot;Database&quot;: &quot; INSERT_DATABASE_NAME&quot;,<br>  &quot;Schema&quot;: &quot; INSERT_SCHEMA_NAME &quot;,<br>  &quot;Action&quot;: &quot;SQL Statement&quot;,<br>  &quot;Snowflake SQL Statement&quot;: <br>    &quot;SELECT AIRPORT, INCIDENT_DATE, INCIDENT_MONTH, INCIDENT_YEAR &quot; + <br>    &quot;FROM TESTTABLE2 WHERE INCIDENT_YEAR = 1994 &quot; + <br>    &quot;ORDER BY INCIDENT_MONTH, INCIDENT_DATE;&quot;,<br>  &quot;Add Condition&quot;: &quot;unchecked&quot;,<br>  &quot;Activity Options&quot;: &quot;Copy From External Datasource&quot;,<br>  &quot;Overwrite&quot;: &quot;Yes&quot;,<br>  &quot;Start or Pause Snowpipe&quot;: &quot;Pause Snowpipe&quot;,<br>  &quot;Statement Timeout&quot;: &quot;10&quot;,<br>  &quot;Show More Options&quot;: &quot;checked&quot;,<br>  &quot;Role&quot;: &quot;SYSADMIN&quot;,<br>  &quot;Warehouse&quot;: &quot; INSERT_SNOWFLAKE_WAREHOUSE&quot;,<br>  &quot;Show Output&quot;: &quot;checked&quot;,<br>  &quot;Host&quot;: &quot; INSERT_HOSTNAME&quot;,<br>  &quot;CreatedBy&quot;: &quot; CREATOR_EMAIL_AUTOMATICALLY_GENERATED&quot;,<br>  &quot;Description&quot;: <br>    &quot;This query fetches details of incidents that occurred in the year 1994, &quot; + <br>    &quot;ordered by month and date.&quot;,<br>  &quot;RunAs&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME&quot;,<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;lochiamocosiUPDATE_DATA-TO-Query_for_a_specific_year&quot;}]<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [<br>      {&quot;Event&quot;: &quot;lochiamocosiQuery_for_a_specific_year-TO-Get_aggregate_stats&quot;}<br>    ]<br>  },<br>  &quot;eventsToDelete&quot;: {<br>    &quot;Type&quot;: &quot;DeleteEvents&quot;,<br>    &quot;Events&quot;: [{&quot;Event&quot;: &quot;lochiamocosiUPDATE_DATA-TO-Query_for_a_specific_year&quot;}]<br>  }<br>}</pre><p><strong>Creating a Snowflake SQL statement job (Get_aggregate_stats)</strong></p><p>To create this job, enter the following details:</p><ul><li><strong>Type:</strong> Job:Snowflake</li><li><strong>Action:</strong> Executes a stored procedure (<em>GetAggregateStatistics</em>) to compute aggregate statistics, returning a JSON string with the results.</li><li><strong>Dependencies:</strong> Waits for Query_for_a_specific_year-TO-Get_aggregate_stats, ensuring that specific data prerequisites are met.</li></ul><p>See an example in the figure below:</p><pre>&quot;Get_aggregate_stats&quot;: {<br>  &quot;Type&quot;: &quot;Job:Snowflake&quot;,<br>  &quot;ConnectionProfile&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME&quot;,<br>  &quot;Action&quot;: &quot;Stored Procedure&quot;,<br>  &quot;Add Condition&quot;: &quot;unchecked&quot;,<br>  &quot;Activity Options&quot;: &quot;Copy From External Datasource&quot;,<br>  &quot;Overwrite&quot;: &quot;Yes&quot;,<br>  &quot;Start or Pause Snowpipe&quot;: &quot;Pause Snowpipe&quot;,<br>  &quot;Show More Options&quot;: &quot;checked&quot;,<br>  &quot;Show Output&quot;: &quot;checked&quot;,<br>  &quot;Database&quot;: &quot; INSERT_DATABASE_NAME&quot;,<br>  &quot;Schema&quot;: &quot; INSERT_SCHEMA_NAME &quot;,<br>  &quot;Stored Procedure Name&quot;: &quot;GetAggregateStatistics&quot;,<br>  &quot;Statement Timeout&quot;: &quot;10&quot;,<br>  &quot;Role&quot;: &quot;SYSADMIN&quot;,<br>  &quot;Warehouse&quot;: &quot; INSERT_SNOWFLAKE_WAREHOUSE&quot;,<br>  &quot;Host&quot;: &quot; INSERT_HOSTNAME&quot;,<br>  &quot;CreatedBy&quot;: &quot; CREATOR_EMAIL_AUTOMATICALLY_GENERATED&quot;,<br>  &quot;Description&quot;: <br>    &quot;This query calculates the average latitude and longitude of incidents &quot; +<br>    &quot;and the total number of incidents per year, only including years &quot; +<br>    &quot;with more than 5 incidents. The procedure will return a JSON string &quot; +<br>    &quot;containing the result set. The procedure executes a SELECT &quot; +<br>    &quot;statement to retrieve aggregate statistics from the table, &quot; +<br>    &quot;and then returns the result as a JSON string.&quot;,<br>  &quot;RunAs&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME&quot;,<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [<br>      {&quot;Event&quot;: &quot;lochiamocosiQuery_for_a_specific_year-TO-Get_aggregate_stats&quot;}<br>    ]<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [<br>      {&quot;Event&quot;: &quot;lochiamocosiGet_aggregate_stats-TO-Select_Data&quot;}<br>    ]<br>  },<br>  &quot;eventsToDelete&quot;: {<br>    &quot;Type&quot;: &quot;DeleteEvents&quot;,<br>    &quot;Events&quot;: [<br>      {&quot;Event&quot;: &quot;lochiamocosiQuery_for_a_specific_year-TO-Get_aggregate_stats&quot;}<br>    ]<br>  }<br>}</pre><p><strong>Creating a Snowflake SQL statement job (Select_Data)</strong></p><p>To create this job, enter the following details:</p><ul><li><strong>Type:</strong> Job:Snowflake</li><li><strong>Action:</strong> Executes a SQL query from a file “<em>select_data3</em>”, targeting incidents in June for a specific operator (United Airlines).</li><li><strong>Description:</strong> This job focuses on extracting specific operational data, demonstrating targeted data retrieval capabilities in Snowflake in a table called “<em>TESTTABLE2”</em>.</li><li><strong>Dependencies:</strong> Waits for Get_aggregate_stats-TO-Select_Data, aligning with data analysis flow.</li></ul><p>See an example in the figure below:</p><pre>&quot;Select_Data&quot;: {<br>  &quot;Type&quot;: &quot;Job:Snowflake&quot;,<br>  &quot;Load SQL File&quot;: <br>    &quot;SELECT * FROM TESTTABLE2 &quot; + <br>    &quot;WHERE incident_month = &#39;6&#39; &quot; + <br>    &quot;AND operator = &#39;UNITED AIRLINES&#39;;&quot;,<br>  &quot;ConnectionProfile&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME&quot;,<br>  &quot;Database&quot;: &quot; INSERT_DATABASE_NAME&quot;,<br>  &quot;Schema&quot;: &quot; INSERT_SCHEMA_NAME &quot;,<br>  &quot;Action&quot;: &quot;Run SQL File&quot;,<br>  &quot;Add Condition&quot;: &quot;unchecked&quot;,<br>  &quot;Activity Options&quot;: &quot;Copy From External Datasource&quot;,<br>  &quot;Overwrite&quot;: &quot;Yes&quot;,<br>  &quot;Start or Pause Snowpipe&quot;: &quot;Pause Snowpipe&quot;,<br>  &quot;Statement Timeout&quot;: &quot;20&quot;,<br>  &quot;Show More Options&quot;: &quot;checked&quot;,<br>  &quot;Role&quot;: &quot;SYSADMIN&quot;,<br>  &quot;Warehouse&quot;: &quot; INSERT_SNOWFLAKE_WAREHOUSE&quot;,<br>  &quot;Show Output&quot;: &quot;checked&quot;,<br>  &quot;Host&quot;: &quot; INSERT_HOSTNAME&quot;,<br>  &quot;CreatedBy&quot;: &quot; CREATOR_EMAIL_AUTOMATICALLY_GENERATED&quot;,<br>  &quot;Description&quot;: <br>    &quot;This query retrieves all information on incidents that occurred &quot; + <br>    &quot;in the Month &#39;6&#39; and where the Operator was &#39;United&#39; &quot; + <br>    &quot;according to the table&quot;,<br>  &quot;RunAs&quot;: &quot; INSERT_CONNECTION_PROFILE_NAME&quot;,<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [<br>      {&quot;Event&quot;: &quot;lochiamocosiGet_aggregate_stats-TO-Select_Data&quot;}<br>    ]<br>  },<br>  &quot;eventsToDelete&quot;: {<br>    &quot;Type&quot;: &quot;DeleteEvents&quot;,<br>    &quot;Events&quot;: [<br>      {&quot;Event&quot;: &quot;lochiamocosiGet_aggregate_stats-TO-Select_Data&quot;}<br>    ]<br>  }<br>}</pre><p><strong>The workflow summary</strong><br> <br> Below is a summary of all the JSON code referenced above and a description of what the entire workflow does:</p><ul><li><strong>S3 Object Transfer</strong>: Transfers a CSV file from one S3 bucket to another, preparing the data for ingestion into Snowflake.<br>* Watches for the specified CSV file in the source bucket and transfers it to the destination bucket once available.<br>* Adds an event upon successful completion to trigger the next step in the workflow.</li><li><strong>CREATE_TABLE</strong>: Dynamically creates or replaces a table in Snowflake using the schema inferred from the transferred CSV file.<br>* Waits for an event indicating that the S3 object transfer has completed before executing.<br>* Executes an SQL statement to create or replace a table in Snowflake, structured according to the CSV file’s inferred schema.</li><li><strong>COPY_INTO_TABLE</strong>: Loads data from the transferred CSV file into the newly created or updated Snowflake table.<br>* Waits for the table creation to complete before executing.<br>* Uses a copy command to load data from the CSV file into the Snowflake table, ensuring data is ready for analysis.<br>* Adds an event to indicate that data loading is complete, allowing subsequent data processing or analysis jobs to begin.</li><li><strong>QUERY_DATA</strong>: Executes an SQL query to retrieve and list the 10 airports with the highest number of incidents from the loaded data.<br>* Waits for data to be loaded into the table before executing.<br>* Extracts valuable insights from the data, specifically focusing on identifying airports with the highest incident counts.</li><li><strong>UPDATE_DATA:</strong> Updates specific records within the Snowflake table, particularly adjusting the time of day column to ensure consistency across the dataset.<br>* This step is crucial for maintaining data integrity and accuracy, and preparing the dataset for reliable analysis.<br>* Executes following the data loading step, as indicated by its dependency on the COPY_INTO_TABLE job’s completion event.</li><li><strong>Query_for_a_specific_year</strong>: Filters and retrieves incident details for a specific year, providing a focused view of data for that period.<br>* Executes after a specific event, likely related to data preparation or a previous analysis step.<br>* Offers detailed insights into incidents by year, aiding in temporal analysis of the data.</li><li><strong>Get_aggregate_stats</strong>: Calls a stored procedure to calculate and return aggregate statistics, such as average latitude and longitude of incidents and total incidents per year, from the data.<br>* Waits for a trigger from a specific query execution to start.<br>* Provides a high-level overview of the data, focusing on aggregate statistics that could inform broader trends or patterns.</li><li><strong>Select_Data</strong>: Runs an SQL query from a file to retrieve information on incidents that occurred in a specific month and were associated with a specific operator.<br>* Waits for the aggregate statistics to be calculated before executing.<br>* Delivers detailed data filtering based on specific criteria, such as time period and operator, to support targeted analysis.</li></ul><p>Throughout this workflow, the use of events to trigger subsequent actions ensures a seamless, automated progression from data transfer and table creation to data loading, querying, and analysis. This orchestrated approach enables efficient data processing and analysis within a cloud-based data warehouse environment, leveraging Snowflake’s capabilities.</p><p><strong>The following images show job completion</strong></p><ul><li>Logs:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Wb3xQ-47X7eo4xgwv7_pAg.png" /></figure><ul><li>Output:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZovcOQePksTW5pC0TiW7OA.png" /></figure><p><strong>External resources showing job completion</strong></p><ul><li><a href="https://www.slideshare.net/secret/x2ICnfoCQSGdCW">Visual view</a></li><li><a href="https://www.slideshare.net/secret/zYjnEhJDVe2Vjz">Log view</a></li></ul><p><strong>Best practices and considerations:</strong></p><ul><li>Make use of <a href="https://docs.snowflake.com/en/sql-reference/sql/create-stage">Snowflake stages</a> when loading data from an external system using Control-M. Control-M transfer jobs like the first one we created in this demo (<em>S3_Object_Transfer</em>) require a Snowflake stage be set up. Stages generally make it much easier to repeatedly load data in a specific format.</li><li>Use the “SYSADMIN” role for most of your Snowflake job processes within Control-M. This has a few benefits:<br>* <strong>Security and principle of least privilege:</strong> The Account Admin role has the highest level of access within a Snowflake account, including the ability to manage users and roles, billing, and account settings. Using Sysadmin for data-related jobs adheres more closely to the principle of least privilege, reducing the risk of accidental or malicious modifications to critical account settings.<br>* <strong>Operational efficiency:</strong> The Sysadmin role is optimized for performing and managing data operations, potentially offering more efficient execution of data-related jobs compared to using an account-wide administrative role, which is not specifically tailored for such tasks.<br>* <strong>Best practices and compliance:</strong> Using the Sysadmin role for database and job management aligns with best practices for managing cloud and database environments. It helps organizations to structure their roles and responsibilities in a way that enhances operational efficiency and security posture.</li></ul><p>Stay tuned for more blogs on Control-M integrations! Let us know if there’s an integration or topic you’d like to learn more about by commenting below. To learn more about how Control-M can help orchestrate you data pipelines, <a href="https://www.bmc.com/it-solutions/control-m-big-data.html">click here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=558185b7d321" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/orchestrating-snowflake-with-control-m-558185b7d321">Orchestrating Snowflake with Control-M</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Operationalizing Responsible AI for Credit Risk with Control-M and Amazon SageMaker]]></title>
            <link>https://medium.com/bmc-digital-it/operationalizing-responsible-ai-for-credit-risk-with-control-m-and-amazon-sagemaker-289fdb5ec8c2?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/289fdb5ec8c2</guid>
            <category><![CDATA[control-m]]></category>
            <category><![CDATA[sagemaker]]></category>
            <category><![CDATA[credit-risk-assessment]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Tue, 05 Aug 2025 16:55:28 GMT</pubDate>
            <atom:updated>2025-08-15T14:34:43.648Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*IIHX-YOm9nolvzcrI6KN7A.jpeg" /></figure><p>By: <a href="https://www.linkedin.com/in/michaeloladugba/">Michael Oladugba</a> and <a href="https://www.linkedin.com/in/samuelduru/">Sam Duru-Nnebue</a></p><p>In today’s financial landscape, making informed and equitable credit decisions is paramount. Machine learning models power critical decisions about credit risk assessment. However, these models must not only be accurate but also fair and explainable. In this post, we’ll explore how to orchestrate an end-to-end credit risk prediction workflow that incorporates bias detection and explainability using Amazon SageMaker and orchestrating this pipeline with Control-M.</p><h3>Business Goal and Objectives</h3><p>The goal: Build a responsible AI workflow that balances operational efficiency with governance in credit decision making.</p><p><strong>Key Objectives:</strong></p><ul><li>Ensure fairness by minimizing bias from sensitive attributes.</li><li>Increase transparency with SHAP-based explanations.</li><li>Automate ML workflows across platforms.</li><li>Meet compliance standards with audit-ready documentation.</li><li>Detect bias before it affects decisions.</li><li>Build stakeholder trust through clear, explainable outcomes.</li></ul><p><strong>Key Considerations-</strong> Deploying ML for credit decisions brings unique challenges:</p><ul><li>Regulatory pressure to prove decisions are free from discrimination.</li><li>Complex workflows that require coordination across teams and tools.</li><li>High demand for explainability from regulators and customers.</li><li>The need for ongoing monitoring to detect drift and maintain fairness.</li></ul><h3>The Pre-Production Validation Imperative</h3><p>Before deploying a credit risk model, AI/ML teams must validate its fairness, explainability, and compliance readiness. This includes bias detection across demographics, SHAP-based explanations, and audit documentation — in this use case requiring coordination across Kubernetes, Amazon SageMaker, and AWS Lambda.</p><p>These steps are highly interdependent: bias detection depends on preprocessing, explainability requires clean data, and compliance outputs rely on completed analyses. Manual execution introduces delays, errors, and inconsistencies.</p><p>By using Control-M, these validation steps are orchestrated into a seamless pipeline. The result: reduced validation time from weeks to days, consistent compliance standards, and clear insights to determine model readiness.</p><h3>Dataset and Use Case Background</h3><p>The use case implemented in this workflow is adapted from <a href="https://github.com/aws-samples/amazon-sagemaker-immersion-day/tree/d01f7b166d290532edc6956d36c70b87a84ab92f/sagemaker-clarify/amazon-sagemaker-credit-risk-prediction-explainability-bias-detection">AWS’s SageMaker Clarify credit risk example</a>, which uses a real-world credit scoring scenario based on the <strong>German Credit Data</strong> dataset.</p><p><strong>Use Case Summary <br></strong>The scenario models a loan approval process where machine learning is used to assess whether an applicant is likely to default. It mirrors operational credit decisions made by financial institutions and introduces ethical challenges around explainability and fairness.</p><p><strong>Dataset Overview</strong></p><ul><li><strong>Source:</strong> <a href="https://archive.ics.uci.edu/ml/datasets/statlog+(german+credit+data)">UCI Statlog German Credit Data</a></li><li><strong>Size:</strong> 1,000 loan applicants</li><li><strong>Target:</strong> Credit classification (good or bad)</li><li><strong>Attributes:</strong> 20 features, including:<br>- Loan duration<br>- Credit amount<br>- Age<br>- Employment status<br>- Housing and marital status<br>- Purpose of the loan</li><li><strong>Sensitive Attributes: </strong>Age and gender (used for bias detection)</li></ul><p>This dataset is ideal for demonstrating regulatory-sensitive AI, as it closely reflects real-world compliance obligations in the lending space. In this implementation, we’ve orchestrated the full workflow around this use case to ensure not only performance, but also fairness, transparency, and auditability.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R-ZPhNcTMKOEaMsmNhekZA.jpeg" /><figcaption>Source: Amazon SageMaker Github examples <a href="https://github.com/aws-samples/amazon-sagemaker-immersion-day/blob/d01f7b166d290532edc6956d36c70b87a84ab92f/sagemaker-clarify/amazon-sagemaker-credit-risk-prediction-explainability-bias-detection/credit_risk_explainability_inference_pipelines_without_output.ipynb">repo</a></figcaption></figure><h3>Solution Architecture</h3><p>The credit risk prediction pipeline, model explainability, and bias detection steps are adapted from <a href="https://github.com/aws-samples/amazon-sagemaker-immersion-day/blob/d01f7b166d290532edc6956d36c70b87a84ab92f/sagemaker-clarify/amazon-sagemaker-credit-risk-prediction-explainability-bias-detection/README.md">this SageMaker Clarify demo</a> published by AWS. We’ve extended this solution by integrating orchestration capabilities through Control-M, enabling robust scheduling, event-driven automation, and governance workflows across SageMaker, Kubernetes, and Lambda. You can find all the code used in this blog in the following repository: <a href="https://github.com/mol-bmc/sagemaker-credit-risk-reliability.git">https://github.com/mol-bmc/sagemaker-credit-risk-reliability.git</a>.</p><p><strong>Technologies used in this scenario :</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*sPEZhxop8jYaD8qFcKuunw.png" /></figure><p>This architecture brings automation, governance, and operational visibility to every step of the credit risk ML lifecycle — from data prep to explainability reporting.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*Z4_4NME4nOfqSt62ZKt93w.png" /></figure><h3>Architecture</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hRPol9wyiCxMKOys5fk8nA.png" /></figure><h3>Workflow Breakdown</h3><p>Let’s examine the key components of our orchestrated workflow:</p><p><strong>Control-M Plug-ins Used:</strong></p><p>This workflow leverages out-of-the-box Control-M Application plug-ins for:</p><ul><li><a href="https://docs.bmc.com/xwiki/bin/view/Control-M-Orchestration/Control-M/Control-M-for-Kubernetes/CTMK8S/Control-M-for-Kubernetes-Overview/"><strong>Kubernetes: </strong></a>To launch and monitor containerized preprocessing jobs</li><li><a href="https://documents.bmc.com/supportu/9.0.21.300/en-US/Documentation/Amazon_SageMaker.htm"><strong>Amazon SageMaker</strong></a>: To trigger model training and SageMaker Clarify pipelines</li><li><a href="https://documents.bmc.com/supportu/9.0.21.300/en-US/Documentation/AWS_Lambda.htm"><strong>AWS Lambda:</strong></a> For serverless data cleanup operations</li></ul><p>These plug-ins simplify integration with cloud-native services, allowing for low-code configuration, native API calls, and consistent event-based orchestration across platforms.</p><p><strong>Connection Profiles</strong></p><p>Before creating a job in Control-M that can execute the jobs in this workflow, make sure the above mentioned plug-ins have been deployed and also <a href="https://documents.bmc.com/supportu/API/Monthly/en-US/Documentation/API_CodeRef_ConnectionProfiles.htm">create connection profiles</a>. A connection profile contains authorization credentials — such as the username, password, and other plug-in-specific parameters — and enables you to connect to the application server with only the connection profile name. Connection profiles can be created using the web interface and then retrieved in JSON format using Control-M’s Automation API.</p><p><strong>Workflow triggered by data asset</strong></p><p>In this use case we assume that the consumer credit data is uploaded to an Amazon S3 bucket in the form of a file (data asset) named SouthGermanCredit.asc. which automatically calls a rule defined in S3 to trigger and an AWS Lambda function that in turn triggers the Control-M workflow. For details on how to set this up please refer to this blog: <a href="https://medium.com/@michaeloladugba1/blog-title-triggering-control-m-saas-jobs-automatically-with-aws-lambda-and-s3-a-step-by-step-ede6df74c653">Triggering Control-M Jobs Automatically with AWS Lambda and S3</a>.</p><p>The code snippets below are extracted from the repository. You can access the full source code for this blog <a href="https://github.com/mol-bmc/sagemaker-credit-risk-reliability.git">here</a>.</p><ol><li><strong>Data Preprocessing (Kubernetes Job)</strong></li></ol><p>The workflow begins with data preprocessing, implemented as a Kubernetes Job in Control-M:</p><pre>&quot;preprocessing-kubernetes-job&quot;: {<br>  &quot;Type&quot;: &quot;Job:Kubernetes&quot;,<br>  &quot;Job Spec Yaml&quot;: &quot;apiVersion: batch/v1\r\nkind: Job\r\nmetadata:\r\n  name: credit-preprocessing-job\r\nspec:\r\n  template:\r\n    spec:\r\n      serviceAccountName: default  # This SA should have S3 access via IAM role\r\n      containers:\r\n      - name: credit-preprocessing\r\n        image: 623469066856.dkr.ecr.us-west-2.amazonaws.com/sagemaker-credit-reliability:latest\r\n        command: [\&quot;/bin/sh\&quot;, \&quot;-c\&quot;, \&quot;python3 /app/preprocess.py &amp;&amp; sleep 60\&quot;]\r\n        env:\r\n        - name: S3_INPUT_PATH\r\n          value: \&quot;s3://sagemaker-sample-files/datasets/tabular/uci_statlog_german_credit_data/SouthGermanCredit.asc\&quot;\r\n        - name: S3_OUTPUT_BUCKET\r\n          value: \&quot;sam-sagemaker-crr\&quot;\r\n        - name: S3_OUTPUT_PREFIX\r\n          value: \&quot;preprocessed-data\&quot;\r\n        - name: AWS_DEFAULT_REGION\r\n          value: \&quot;us-west-2\&quot;\r\n&quot;,<br>  &quot;ConnectionProfile&quot;: &quot;MOL-K8S-CONNECTION-PROFILE&quot;,<br>  &quot;Get Pod Logs&quot;: &quot;Get Logs&quot;,<br>  &quot;Host&quot;: &quot;mol-agent-installation-sts-0&quot;,<br>  &quot;Application&quot;: &quot;ML_CreditRisk_Bias_Detection&quot;,<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [{<br>      &quot;Event&quot;: &quot;preprocessing-kubernetes-job-TO-AWS_SageMaker_Job_2&quot;<br>    }]<br>  }<br>}</pre><p>This job:</p><ul><li>Pulls raw credit data from S3</li><li>Performs feature engineering and data cleansing</li><li>Stores the processed dataset back to S3</li><li>Signals completion to trigger the next step</li></ul><p><strong>2. Model Training Pipeline (SageMaker)</strong></p><p>Once preprocessing completes, Control-M triggers the SageMaker model training pipeline:</p><pre>&quot;Sagemaker-Model-Training&quot;: {<br>  &quot;Type&quot;: &quot;Job:AWS SageMaker&quot;,<br>  &quot;Pipeline Name&quot;: &quot;CRRModelPipeline&quot;,<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{<br>      &quot;Event&quot;: &quot;preprocessing-kubernetes-job-TO-AWS_SageMaker_Job_2&quot;<br>    }]<br>  }<br>}]<br> }<br>}</pre><p>The CRRModelPipeline handles:</p><ul><li>Splitting data into training/validation sets</li><li>Training a machine learning model</li><li>Evaluating model performance</li><li>Creating a model artifact for deployment</li></ul><p><strong>3. Cleanup Operations (Lambda)</strong></p><p>After model training, a Lambda function performs cleanup operations:</p><pre>&quot;sagemaker-crr-clean-files&quot;: {<br>  &quot;Type&quot;: &quot;Job:AWS Lambda&quot;,<br>  &quot;Function Name&quot;: &quot;sagemaker-crr-clean-files&quot;,<br>  &quot;Parameters&quot;: &quot;{}&quot;,<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{<br>      &quot;Event&quot;: &quot;Sagemaker-Model-Training-TO-sagemaker-crr-clean-files&quot;<br>    }]<br>  }<br>}</pre><p>This step ensures:</p><ul><li><strong>Column Name Standardization:</strong> Removes preprocessing artifacts like ‘onehotencoder__’ and ‘remainder__’ prefixes from column names that were added during the SageMaker preprocessing pipeline</li><li><strong>Data Format Optimization:</strong> Cleans and standardizes the training and validation datasets for downstream bias detection analysis</li><li><strong>S3 Data Organization:</strong> Creates cleaned versions of the datasets (train_cleaned.csv and validation_cleaned.csv) that are properly formatted for SageMaker Clarify</li></ul><p><strong>4. Bias Detection and Explainability (SageMaker Clarify)</strong></p><p>The final step in our workflow leverages SageMaker Clarify for responsible AI practices:</p><pre>&quot;sagemaker-crr-bias-detection-explainability&quot;: {<br>  &quot;Type&quot;: &quot;Job:AWS SageMaker&quot;,<br>  &quot;Pipeline Name&quot;: &quot;BiasDetectionExplainabilityPipeline&quot;,<br>  &quot;eventsToWaitFor&quot;: {<br>    &quot;Type&quot;: &quot;WaitForEvents&quot;,<br>    &quot;Events&quot;: [{<br>      &quot;Event&quot;: &quot;sagemaker-crr-clean-files-TO-sagemaker-crr-bias-detection-explainability&quot;<br>    }]<br>  }<br>}</pre><p>This pipeline:</p><ul><li>Analyzes the model for potential biases (pre-training and post-training)</li><li>Generates SHAP values to explain model predictions</li><li>Creates visualization artifacts for stakeholder review</li><li>Generates compliance documentation</li></ul><h3>OUTPUT IMAGES:</h3><p>Here is what the defined full workflow looks like in Control-M:</p><p><strong>Planning Domain: </strong>This is where the full ML workflow is visually defined and configured. It includes four jobs: a Kubernetes-based preprocessing job, the SageMaker training pipeline, a file cleaning Lambda function, and a final SageMaker pipeline for bias detection and explainability. Each job is sequentially linked, ensuring a smooth, automated progression from raw data ingestion to model fairness evaluation. This domain defines how, when, and under what conditions each job is triggered and monitored.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/1*7IWYQx-7ZNHpgvleCcHZkQ.png" /></figure><p><strong>Monitoring Domain: </strong>This shows the real-time execution status of each job in the workflow. All four jobs, from preprocessing to explainability, have successfully completed, with exact start and end timestamps displayed. This interface is used by operators and engineers to monitor job health, duration, and flow dependencies in production, ensuring the full ML lifecycle executes reliably.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/587/1*VtH31XfHSr6VPhbEGcPGqg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/587/1*C7q-6U7DVZ3m2d5ym7eitA.png" /></figure><p><strong>SageMaker Pipelines executed in the Workflow:</strong></p><p><strong><em>The Model Training</em></strong> pipeline included XGBoost training, Model Evaluation, and the Model Deployment steps. First, the pipeline trains an XGBoost model on preprocessed credit application data using the train_xgboost.py script. This script loads training data from S3, fits the model, and outputs a compressed model artifact. The next step, evaluate.py, evaluates the model’s performance using metrics like accuracy and AUC on a validation dataset to ensure the model meets performance standards. Finally, the deploy_model2.py script deploys the trained model to a SageMaker endpoint, making it accessible for real-time inference. This endpoint is used to score incoming credit applications and return risk predictions instantly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/746/1*vH8e5kLH0H_3uC7G7QAkLQ.png" /></figure><p><strong><em>The Bias Detection and Explainability</em></strong> pipeline, which includes Bias Detection and SHAP Explainability steps, uses SageMaker Clarify to assess fairness and interpretability of the deployed credit risk model. It runs post-training bias checks to identify any discrimination based on sensitive attributes like gender and uses SHAP to explain individual predictions. This pipeline ensures that the model is not only accurate but also fair and transparent, providing visual artifacts and reports that support regulatory audits and build trust with stakeholders.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*R9ca-ZqXqnYTSH35zlcYoQ.png" /></figure><h3>Orchestration Benefits with Control-M</h3><p>Control-M provides several key benefits for this ML workflow:</p><ol><li><strong>Event-Driven Execution</strong></li></ol><p>The workflow uses sophisticated event coordination to manage job dependencies:</p><pre>json<br>&quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [{<br>        &quot;Event&quot;: &quot;preprocessing-kubernetes-job-TO-AWS_SageMaker_Job_2&quot;<br>    }]<br>}</pre><p><strong>What’s happening in this configuration:</strong></p><ul><li><strong>Event Generation:</strong> When the preprocessing Kubernetes job completes successfully, it automatically generates an event named “preprocessing-kubernetes-job-TO-AWS_SageMaker_Job_2”</li><li><strong>Event Naming Convention:</strong> The event name follows a clear pattern: [source-job]-TO-[target-job], making dependencies immediately visible</li><li><strong>Automatic Triggering: </strong>The SageMaker training job is configured to wait for this specific event before starting execution</li><li><strong>Failure Handling:</strong> If the preprocessing job fails, no event is generated, preventing downstream jobs from processing invalid data</li></ul><p>This approach ensures:</p><ul><li>Jobs execute in the correct sequence with clear dependency management</li><li>Failed jobs don’t trigger downstream processes</li><li>Real-time status updates across the entire workflow</li><li>Automatic retry logic for transient failures</li></ul><p><strong>2. Advanced Scheduling Capabilities</strong></p><p>The workflow leverages Control-M’s flexible scheduling system:</p><pre>json<br>&quot;When&quot;: {<br>    &quot;RuleBasedCalendars&quot;: {<br>        &quot;Included&quot;: [&quot;EVERYDAY&quot;],<br>        &quot;EVERYDAY&quot;: {<br>            &quot;Type&quot;: &quot;Calendar:RuleBased&quot;,<br>            &quot;When&quot;: {<br>                &quot;DaysRelation&quot;: &quot;OR&quot;,<br>                &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>                &quot;MonthDays&quot;: [&quot;ALL&quot;]<br>            }<br>        }<br>    }<br>}</pre><p><strong>Breaking down the scheduling configuration:</strong></p><ul><li><strong>Calendar Definition:</strong> “EVERYDAY” creates a custom calendar rule that Control-M references for scheduling decisions</li><li><strong>Rule-Based Logic:</strong> The “Calendar:RuleBased” type allows complex scheduling rules beyond simple cron expressions</li><li><strong>Day Selection Strategy:</strong> <br>- “DaysRelation”: “OR” means the job runs if ANY of the specified conditions are met<br>- “WeekDays”: [“NONE”] indicates no specific weekday restrictions<br>- “MonthDays”: [“ALL”] means the job runs on every day of the month</li><li><strong>Flexible Execution:</strong> This configuration essentially creates a daily schedule while maintaining the flexibility to easily modify timing rules</li></ul><p>This scheduling flexibility enables:</p><ul><li>Regular Model Retraining: Automatically retrain models with fresh data on a predictable schedule</li><li>Business-Aligned Scheduling: Easily align with reporting cycles and business requirements by modifying calendar rules</li><li>Holiday and Weekend Handling: Intelligent scheduling around business calendars without manual intervention</li><li>SLA Management: Ensure workflows are completed within required timeframes with built-in scheduling constraints.</li></ul><p><strong>3. Cross-Platform Integration</strong></p><p>Control-M seamlessly integrates different computing platforms:</p><ul><li>Kubernetes for preprocessing</li><li>SageMaker for ML operations</li><li>Lambda for auxiliary functions</li></ul><p>This eliminates the need for custom integration code or multiple workflow tools.</p><p><strong>4. Monitoring and Visibility</strong></p><p>Control-M provides visibility across the entire workflow:</p><ul><li>Real-time status monitoring</li><li>Detailed job logs</li><li>Historical execution records</li><li>SLA management</li></ul><p><strong>Implementing Responsible AI Practices</strong></p><p>Beyond the technical workflow, this implementation addresses responsible AI requirements:</p><p><strong>Bias Detection</strong></p><p>SageMaker Clarify helps identify potential biases:</p><ul><li>Pre-training data bias metrics</li><li>Post-training model bias metrics</li><li>Analysis of sensitive attributes (age, gender, etc.)</li></ul><p><strong>Model Explainability</strong></p><p>Explainability features provide insights into model decisions:</p><ul><li>Feature importance scores</li><li>SHAP values for individual predictions</li><li>Counterfactual examples for rejected applications</li></ul><p><strong>Compliance Documentation</strong></p><p>The workflow generates documentation for regulatory compliance:</p><ul><li>Model cards with performance metrics</li><li>Bias assessment reports</li><li>Explainability artifacts</li></ul><h3>Understanding Key Concepts</h3><p><strong>SHAP (SHapley Additive exPlanations) Explainability</strong></p><p>SHAP values provide a unified framework for interpreting machine learning model predictions by quantifying each feature’s contribution to individual predictions.</p><p><strong>How SHAP Works in Credit Risk:</strong></p><ul><li>For each loan application, SHAP calculates how much each feature (income, credit history, debt-to-income ratio) pushes the prediction toward approval or denial</li><li>Values are additive: the sum of all SHAP values equals the difference between the model’s prediction and the average prediction</li><li>Positive SHAP values indicate features that increase approval likelihood, while negative values indicate features that decrease it</li></ul><p><strong>Business Value:</strong></p><ul><li>Customer Communication: Loan officers can explain to applicants exactly why their application was approved or denied</li><li>Regulatory Compliance: Provides auditable explanations for regulatory review</li><li>Model Debugging: Data scientists can identify when models rely on unexpected or problematic features</li></ul><h3>Outcomes and Impact</h3><p><strong>Operational Excellence:</strong></p><p><strong>Automation Efficiency: </strong>The end-to-end workflow has achieved a high level of automation, reducing manual intervention from many hours per week to just a few hours for monitoring and exception handling. This allows data science teams to focus on model innovation rather than operational tasks.</p><p><strong>Deployment Speed: </strong>Model deployment time has decreased from weeks to days, enabling faster response to market changes and regulatory requirements. The automated pipeline eliminates the traditional handoffs between teams that create delays.</p><p><strong>Error Reduction:</strong> Automated workflows have reduced human errors drastically, particularly in data preprocessing and model evaluation steps. Standardized processes ensure consistent quality across all model deployments.</p><p>By combining Control-M’s enterprise orchestration capabilities with SageMaker’s advanced machine learning features, we’ve created an automated, responsible credit risk prediction workflow that transforms how financial institutions approach AI governance. This solution ensures that:</p><ol><li><strong>Models are consistently trained</strong> on schedule with the latest data and embedded fairness constraints</li><li><strong>All processing steps execute reliably</strong> in the correct sequence with comprehensive error handling</li><li><strong>Models are automatically evaluated</strong> for bias, explainability, and performance against regulatory standards</li><li><strong>Compliance documentation is generated</strong> automatically, reducing audit preparation time and ensuring consistency</li><li><strong>Stakeholders receive clear insights</strong> into model behavior and decision factors through automated SHAP explanations</li></ol><p>This implementation demonstrates how financial institutions can leverage modern orchestration and ML tools to build robust, fair, and explainable credit risk models while dramatically improving operational efficiency and regulatory compliance.</p><p>The automated workflow has proven that responsible AI practices don’t have to slow down innovation — they can actually accelerate it by embedding governance into the development process rather than treating it as a separate, time-consuming step.</p><h3>Real-World Implementation Results</h3><p>To demonstrate the practical impact of our automated responsible AI workflow, let’s examine actual output from the execution of the bias detection and explainability pipeline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*gUbCEQqRLac5EzUm_UERmA.png" /></figure><p><strong>SageMaker Clarify Analysis Report</strong></p><p>The following results showcase the comprehensive analysis generated by our automated workflow:</p><p><strong>Model Configuration Details</strong></p><ul><li><strong>Model Used</strong>: XGBoost model</li><li><strong>Features Analyzed</strong>: 50 total features from the credit risk dataset</li><li><strong>Analysis Method</strong>: KernelSHAP explanations with 2,000 samples</li><li><strong>Infrastructure</strong>: Deployed on ml.m5.xlarge instance for optimal performance</li></ul><p><strong>SHAP Explainability Results</strong></p><p>The automated SHAP analysis revealed several key insights:</p><p><strong>Feature Attribution Analysis</strong>: The system computed KernelSHAP explanations across all 50 features, identifying the 10 most influential features for each prediction. This automated analysis eliminates the manual effort previously required to understand model behavior.</p><p><strong>Individual Instance Explanations</strong>: Each credit application receives a detailed breakdown showing how specific features contributed to the approval or denial decision. The visualization uses a red-blue color scale where:</p><ul><li><strong>Red indicators</strong>: Higher feature values that typically favor approval</li><li><strong>Blue indicators</strong>: Lower feature values that may indicate higher risk</li><li><strong>SHAP values</strong>: Quantify each feature’s specific contribution to the final decision</li></ul><p><strong>Baseline Establishment</strong>: The system automatically established a baseline using representative feature values:</p><pre>json<br>&quot;baseline&quot;: [<br>    [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,<br>     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,<br>     0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,<br>     1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,<br>     4.0, 36.0, 10974.0, 1.0, 1.0, 4.0, 2.0, 26.0, 2.0, 2.0]<br>]</pre><p>This baseline represents typical applicant characteristics and serves as the reference point for computing individual SHAP values.</p><p><strong>Analysis Configuration Insights</strong></p><p>The automated configuration demonstrates several best practices:</p><p><strong>Robust Sampling</strong>: Using 2,000 samples ensures statistical significance while maintaining reasonable computation time.</p><p><strong>Logit Transformation</strong>: The “use_logit”: true setting provides more interpretable explanations by working with log-odds rather than raw probabilities.</p><p><strong>Local SHAP Values</strong>: Saving local SHAP values enables detailed audit trails and supports regulatory requirements for decision explanations.</p><p><strong>Mean Absolute Aggregation</strong>: The “mean_abs” aggregation method provides stable, interpretable feature importance rankings.</p><p><strong>Automated Documentation Benefits</strong></p><p>This analysis report exemplifies how the automated workflow delivers immediate value:</p><p><strong>Regulatory Compliance</strong>: The detailed configuration parameters and baseline values provide auditors with complete transparency into the model’s decision-making process.</p><p><strong>Operational Efficiency</strong>: What previously required days of manual analysis is now generated automatically within hours of model training completion.</p><p><strong>Stakeholder Communication</strong>: The standardized report format enables consistent communication with customers, regulators, and internal teams.</p><p><strong>Quality Assurance</strong>: Automated generation eliminates human errors in analysis configuration and ensures consistent methodology across all model deployments.</p><p><strong>Impact on Credit Decision Process</strong></p><p>This automated explainability analysis has transformed how the organization handles credit decisions:</p><ul><li><strong>Customer Service</strong>: Loan officers can now provide specific, data-driven explanations for any credit decision</li><li><strong>Appeal Process</strong>: Customers who are denied can receive concrete guidance on which factors to improve</li><li><strong>Risk Management</strong>: The consistent analysis helps identify emerging patterns in credit risk factors</li><li><strong>Compliance Reporting</strong>: Regulatory reports can be generated instantly with full documentation of the decision process</li></ul><p><strong>Next Steps and Future Enhancements</strong></p><p>To further enhance this workflow and expand its capabilities, consider implementing:</p><p><strong>Advanced Monitoring Capabilities</strong></p><ul><li><strong>Concept Drift Detection</strong>: Implement statistical tests to identify when model assumptions become invalid due to changing market conditions</li><li><strong>Performance Degradation Alerts</strong>: Set up automated monitoring that triggers retraining when model accuracy drops below specified thresholds</li><li><strong>Real-time Bias Monitoring</strong>: Extend bias detection to monitor live predictions, not just batch training processes</li><li><strong>Enhanced Model Management</strong></li><li><strong>A/B Testing Framework</strong>: Implement controlled experiments to compare model versions before full deployment</li><li><strong>Champion/Challenger Models</strong>: Maintain multiple model versions and automatically promote the best performer</li><li><strong>Model Ensemble Strategies</strong>: Combine multiple models to improve both accuracy and fairness</li></ul><p><strong>Business Process Integration</strong></p><ul><li><strong>Approval Workflow Integration</strong>: Connect bias detection results to business approval processes, requiring human review for high-risk decisions</li><li><strong>Customer Communication</strong>: Automatically generate personalized explanations for credit decisions that customers can easily understand</li><li><strong>Regulatory Reporting</strong>: Create automated reports that feed directly into regulatory filing systems</li></ul><p><strong>Advanced Analytics</strong></p><ul><li><strong>Counterfactual Analysis</strong>: Generate “what-if” scenarios showing customers exactly what changes would improve their approval chances</li><li><strong>Segment-Specific Models</strong>: Develop specialized models for different customer segments while maintaining overall fairness</li><li><strong>Economic Impact Analysis</strong>: Quantify the business impact of bias reduction and explainability improvements</li></ul><p>By continuously evolving your ML operations with these enhancements, you can ensure your credit risk models remain at the forefront of both accuracy and responsible AI practices, setting new industry standards for fair and transparent lending decisions.<br>_________________________________________________________________<br><em>This blog post demonstrates the integration of Control-M with Amazon SageMaker for orchestrating responsible AI workflows. For more information on implementing similar solutions, contact your BMC or AWS representative.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=289fdb5ec8c2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/operationalizing-responsible-ai-for-credit-risk-with-control-m-and-amazon-sagemaker-289fdb5ec8c2">Operationalizing Responsible AI for Credit Risk with Control-M and Amazon SageMaker</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[LLMOps — Tasks, Workflow and Personas]]></title>
            <link>https://medium.com/bmc-digital-it/llmops-tasks-workflow-and-personas-df3582cb3847?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/df3582cb3847</guid>
            <category><![CDATA[workflow-orchestration]]></category>
            <category><![CDATA[control-m]]></category>
            <category><![CDATA[llmops]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Fri, 11 Jul 2025 15:11:31 GMT</pubDate>
            <atom:updated>2025-07-11T15:11:31.566Z</atom:updated>
            <content:encoded><![CDATA[<h3>LLMOps — Tasks, Workflow and Personas</h3><p>By <a href="https://www.linkedin.com/in/sumit-p-2127544/">Sumit Pal</a> and <a href="https://www.linkedin.com/in/basil-faruqui-b1a4b059/">Basil Faruqui</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*KS7Wo-ryaJ1A6KJYS6KoAg.jpeg" /></figure><p><em>Disclaimer — This blog post does not discuss Large Language Model Operations (LLMOps) from the point of view of building or fine-tuning LLMs or LLMOps for SLM (small language models). LLMOps as discussed in this post is part of building LLM powered AI applications.</em></p><p>Despite the excitement around generative AI (GenAI), many LLM-based applications fail to move beyond proof of concept. Gartner predicts that by 2025, over 30% of GenAI projects will be abandoned due to poor data quality, rising costs, lack of governance, or unclear business value.</p><p>This even with the time to develop being faster than with traditional ML and NLP approaches. The main reasons for this are low user value, low performance, suffering from accuracy and failing to clear compliance and regulatory issues. Despite their transformative potential, LLMs require methodical execution across traditional lifecycle steps. Continuing from part 1 of the LLMOps blog series, part 2 dives into details of the stages, components, associated tasks, workflow and personas in the LLMOps practice.</p><h3>LLMOps Stages</h3><p>It is prudent to involve LLMOps practice from the beginning of AI application development, from outlining use cases to deployment and post deployment of LLM-powered applications. Figure 1 shows the different stages of LLM application development and the associated tasks across the stages. LLMs and foundational models are evolving rapidly. Hype often overshadows the challenges involved. It is imperative to involve personas with LLM experience and expertise to integrate LLMs within the business processes of an enterprise.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*A7j4osuvX6PwfRlsh17jCQ.png" /><figcaption>Figure 1 — LLMOps stages and the associated tasks</figcaption></figure><p>The set of tasks data, ML and AI teams need, to build applications includes the following:</p><ul><li>Identify business specific use cases for LLMs backed up by metrics outlining the ROI of using an AI-driven approach.</li><li>Selecting an LLM provider — With so many LLM providers to choose from, organizations need to evaluate which provider to use based on factors like business priorities, performance, latency, functionality, bias mitigation, governance and security. Data and AI engineers need to define the criteria and select LLM providers accordingly. At the end of this step, teams should have a list of the few top proprietary or open source LLMs to leverage for their applications.</li><li>LLM integration — Required both for Retrieval Augmented Generation (RAG) -based solutions as well as applications that depend on LLM API invocations. This involves subtasks like prompt engineering to develop a set of prompts and associated templates and store them in a prompt catalog that supports version control.<br>This step involves customizing LLMs with RAG patterns especially when using proprietary data and domain context adaptation. This requires selecting vector databases, data pre-processing, data chunking — algorithms and choices around ranking the results and then augmenting the prompt.</li><li>Cross cutting tasks that need to be applied across all tasks include: security management, observability, monitoring, feedback loop and data governance. These require defining, outlining and building metrics to track security, accuracy, bias and ethical considerations based on types of end-users and geographies where the application will be deployed.</li></ul><h3>Role of workflow &amp; orchestration in LLMOps</h3><p>AI-based workflows are becoming increasingly common as LLMs mature and permeate in the enterprise and embed themselves across different applications in the business processes. To build useful applications, GenAI needs to be integrated with existing systems and process workflows. It involves integrating with prompt templates, APIs, and tool invocations to trigger actions across systems with frameworks like LangChain and LlamaIndex to connect models with data sources to orchestrate the flow of information across components.</p><p>Diversity of tasks in the workflow chain necessitates a strategic approach to orchestration, which includes different facets of a broader orchestration strategy. From choosing the right LLM model to parameters configuration, understanding and tuning the economics of scale, adhering to SLAs, environmental, security and privacy metrics to evaluate the outcomes are critical aspects. LLM workflows also need to ensure durable, reliable, scalable fault tolerant execution of tasks that can be re-tried or rolled back.</p><p>Data, ML and LLM orchestration ensures all tasks in the workflow chain work coherently to address multi-dimensional challenges in creating successful AI applications. Workflow and data orchestration tools are rapidly evolving to integrate with LLMs and incorporate LLMs as a part of the overall business processes into data and ML pipelines. This involves invoking LLMs and agents, orchestrating multi-step AI reasoning to validate responses, handle branching and conditional logic along with error and exception handling with retries and human-in-the-loop feedback. Data privacy, security, and cost considerations are essential components of the LLMOps workflow.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*zZkCla4ye9J7TSCbNWFZpg.png" /><figcaption>Figure 2 shows the LLMOps workflow at a high level as integrated with other processes and tasks in building AI-driven applications</figcaption></figure><h3>Industry use cases:</h3><h4>Supply Chain Optimization</h4><p>A global manufacturing company improves supply chain resilience by orchestrating an ETL pipeline that extracts real-time inventory, supplier performance, and logistics data from multiple ERP and warehouse management systems. This structured data feeds an LLM workflow that analyzes supplier risks, predicts potential delays, and drafts proactive mitigation strategies. For instance, if a shipment delay is detected, the LLM generates recommended alternative sourcing plans and auto-drafts supplier communications. The orchestration platform coordinates the full data ingestion, LLM-based reasoning, exception handling, and integration back into procurement and supply chain management applications — enhancing decision-making speed and significantly reducing supply chain disruption.</p><h4>Accelerate customer onboarding</h4><p>Let’s consider the example of a financial services company which automates customer onboarding by orchestrating an ETL pipeline that extracts customer data from core banking systems, CRM and ERP applications, performs data quality checks, enriches the data, and then feeds it into an LLM-based workflow. The LLM generates personalized onboarding documents, explains terms and conditions in natural language, and answers customer queries through an AI assistant. Orchestration tools manage the data pipeline, model invocation, and dynamic prompt generation based on customer profiles, and human-in-the-loop approvals — ensuring compliance, accuracy, and customer satisfaction while significantly reducing manual workload and overall onboarding time.</p><h3>Personas and Skillsets for LLMOps</h3><p>LLMOps demands a multifaceted approach that merges technical skills with practical considerations. This comprises building necessary data pipelines and deploying them as well as the skills to ensure models are performant, optimal, well governed, grounded and cost-effective. Organizations cannot build LLM-driven applications without proper data management, data and ML engineering pipelines with DataOps and MLOps practices. Some of the key personas involved include:</p><ul><li>Data and AI Engineers (LLM focused) /developers who select, test, evaluate LLMs, develop the GenAI applications this could also include AI application developers who build AI applications with backend frameworks like Langchain, front end frameworks like Streamlit of the GenAI application.</li><li>Prompt engineers who are expert prompters who create and manage prompts. They build, test, version control prompts and associate prompts with inputs and corresponding outputs.</li><li>DevOps and DataOps personas who set up environments, automate deployments for the data pipeline, ML pipelines and infrastructure supporting them.</li><li>AI governance teams comprising of auditors, risk and compliance teams who review output from models to check bias, ethics, verify data privacy and leakage issues.</li><li>AI testers who test applications in coordination with AI product managers to ensure compliance and quality of results across the use cases.</li><li>GenAI end users who consume outputs from GenAI applications and share data to rate the quality of output.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*_Pw9qY3siLQuskVFo8n5PQ.png" /><figcaption>Figure 3. shows the associated personas across the different tasks and stages in LLMOps</figcaption></figure><h3>LLMOps life cycle</h3><p>LLMOps life cycle management has become a critical step to ensure the success of GenAI applications in enterprises. Since LLMs generate free-form text, it accelerates some of the steps and processes but additionally introduce new complexities that require new tools and methodologies and extra caution and care when deploying to production for general use.</p><p>LLMOps life cycle can be divided into the following areas:</p><p><strong>Data preparation</strong> — This is the most time-consuming task for organizations that leverage the RAG pattern to integrate LLMs with their proprietary data to improve accuracy and performance in providing context to the LLMs. This step includes rigorous data cleaning, elimination of bad inconsistent data.</p><p>Leveraging proprietary datasets with the RAG patterns requires data preparation and building the right kind of chunking approach. Proprietary data needs to be cleaned and anonymized to prevent unintentional data leakage of sensitive information. For evaluation, data collection and preparation of the collected data for proper response evaluation is a critical step. Lack of comprehensive evaluation with the right datasets leads to limited insights into model behavior and establishing product reliability.</p><p><strong>Deployment </strong>— Post deployment, LLM applications require ensuring accessibility and prompt responsiveness across diverse application scenarios. Applications need to maintain high operational efficiency and rapid response times especially in large-scale enterprise applications. Achieving this level of responsiveness involves thorough planning and optimization of both the models and the infrastructure. Key strategies for performance include data caching and applying load balancing to manage user requests efficiently.</p><p><strong>LLM Observability </strong>— LLM observability is a critical element in the modern LLM infrastructure stack. The goal of observability is to proactively detect before an issue emerges and provide analytics for deeper inspection and diagnose root cause before it impacts business and end users. The objective is to establish a deployment environment where LLMs consistently deliver optimal performance and offer users swift and precise language processing capabilities across various applications.</p><p>Monitoring application behavior in real-time for hallucination, accuracy, security, ethical and compliance issues and course correcting is extremely challenging when developing LLM application. Neglecting monitoring can seriously hamper insights and affect product adoption and performance.</p><p>Good observability principles should include a plan what to observe — from inputs to outputs to the system itself for SLAs and failures. Ideally for GenAI applications both input and response from LLMs should be observed for bias and ethical considerations as well as prompt injections, apart from the usual observability metrics associated with performance, latency, scalability and fault-tolerance to ensure post-deployment LLM applications are operating as expected.</p><p>LLM observability with continuous monitoring that tracks relevant KPIs ensures AI applications maintain accuracy, response time, to control error rates ensuring output remains consistent and dependable within certain thresholds.</p><p>With AI application, just tracking metrics and logs isn’t enough, monitoring bad inputs, identifying prompt failures with logs and traces and calls record tracking responses are imperative to diagnose quality issues for trust, reliability and compliance.</p><p>Modern infrastructures, especially for AI applications, have gotten more complex and having observability solutions in place is an essential process in identifying and troubleshooting reliability and latency issues. AI systems are highly distributed, making observability more critical and challenging. LLM-powered applications can quickly become cost prohibitive based on concurrent calls with large prompt context windows, observability also helps organizations to analyze token usage and call metrics to keep infrastructure spending in control.</p><p>Governance, security and evaluation — Governance and compliance are vital in LLMOps. This involves detecting compliance, privacy violations and risk mitigation to preserve integrity of the applications and user trust and acceptance. LLM applications should adhere to national, regional and local regulations. Effectively implementing transparency, explainability and accountability in all responses are work in progress as the LLM stack and landscape matures.</p><p><strong>Evaluation </strong>— LLM-based applications also require evaluation and tooling. Methodology around this is evolving. Text evaluation needs metrics like factual consistency, relevance, and coherence. Evaluation of both input and output is a critical step in the life cycle of an LLM application development and unless these are standardized and continuously evolve along with the evolution of the product and use cases, LLM-driven application will struggle to gain adoption in production. Evaluation is the bottleneck throughout the development life cycle. Testing/evaluation are critical elements across each step of the LLM application development life cycle, from model selection to experimentation and deployment. Measuring correctness of text data is difficult to define and implement. LLMs are also susceptible to prompt injection attacks which can trick LLMs to ignore instructions and generate undesirable content.</p><p><strong>Infrastructure </strong>— Deploying, configuring and monitoring the data pipeline to support RAG architecture, involves various components in the chain. These include storage of unstructured and structured data, processing pipeline to chunk the data and create embeddings (by invoking LLM models with APIs) and storing them in a vector database. Storing and version control of prompts and LLM responses to track performance, optimize tuning and control costs based on token usage are critical to improve the quality of the application.</p><h3>Future of LLMOps</h3><p>In the rapidly evolving world of AI, it is hard to predict the future of LLMOps. But LLMOps are here to stay, just like DevOps, DataOps and MLOps and will weave in as a part of the technology and data stack.</p><p>Of late, AI agents have been the talk of the AI universe along with agentic workflows. Agentic workflows are AI-driven processes where tasks are dynamically and autonomously executed with minimal human intervention. Agentic workflows coordinate across models with memory, planning, reasoning, and integration with external tools. This has given rise to new Ops involving agents called AgentOps.</p><p>Each of these discrete practices of XOps (Devops, Dataops, MLOps, LLMOps) will need to be coordinated, synchronized and orchestrated by higher level tools like <a href="https://www.bmc.com/it-solutions/control-m.html">Control-M</a> from BMC to build end-to-end business processes in enterprises. Workflow leveraging AI systems will be non-deterministic and hence there will be a need of constant monitoring, evaluation and decision making that make tools like Control-M indispensable for enterprises as they race to adapt AI technologies.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=df3582cb3847" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/llmops-tasks-workflow-and-personas-df3582cb3847">LLMOps — Tasks, Workflow and Personas</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Orchestrating a multi-cloud fraud analytics pipeline with Control-M]]></title>
            <link>https://medium.com/bmc-digital-it/orchestrating-a-multi-cloud-fraud-analytics-pipeline-with-control-m-a23907adc1af?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/a23907adc1af</guid>
            <category><![CDATA[control-m]]></category>
            <category><![CDATA[multi-cloud]]></category>
            <category><![CDATA[orchestration]]></category>
            <category><![CDATA[fraud-analytics]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Mon, 30 Jun 2025 14:44:03 GMT</pubDate>
            <atom:updated>2025-06-23T21:28:28.453Z</atom:updated>
            <content:encoded><![CDATA[<p>By: <a href="https://www.linkedin.com/in/michaeloladugba/">Michael Oladugba</a>, <a href="https://www.linkedin.com/in/samuelduru/">Sam Duru-Nnebue</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*KISPrkYc5mTcMs7Eu8mbiQ.jpeg" /></figure><p>Financial Fraud Detection is the process of monitoring transactions and customer behavior to identify and stop fraudulent activity. To get highly effective fraud detection models, lots of transaction data is aggregated and analyzed. In this blog we will discuss the latter with specific focus on orchestrating a multi-cloud fraud analysis pipeline. The dataset used for this exercise is sourced from Kaggle. The data card for this dataset offers the following detail:</p><blockquote>“This dataset presents a synthetic representation of mobile money transactions, meticulously crafted to mirror the complexities of real-world financial activities while integrating fraudulent behaviors for research purposes. Derived from a simulator named PaySim, which utilizes aggregated data from actual financial logs of a mobile money service in an African country, this dataset aims to fill the gap in publicly available financial datasets for fraud detection studies. It encompasses a variety of transaction types including CASH-IN, CASH-OUT, DEBIT, PAYMENT, and TRANSFER over a simulated period of 30 days, providing a comprehensive environment for evaluating fraud detection methodologies. By addressing the intrinsic privacy concerns associated with financial transactions, this dataset offers a unique resource for researchers and analysts in the field of financial security and fraud detection.”</blockquote><h3>Dataset Structure</h3><p>The csv file on Kaggle includes the following columns of data:</p><ul><li>step: Represents a unit of time in the real world, with 1 step equating to 1 hour. The total simulation spans 744 steps, equivalent to 30 days.</li><li>type: Transaction types include CASH-IN, CASH-OUT, DEBIT, PAYMENT, and TRANSFER.</li><li>amount: The transaction amount in the local currency.</li><li>nameOrig: The customer initiating the transaction.</li><li>oldbalanceOrg: The initial balance before the transaction.</li><li>newbalanceOrig: The new balance after the transaction.</li><li>nameDest: The transaction’s recipient customer.</li><li>oldbalanceDest: The initial recipient’s balance before the transaction. Not applicable for customers identified by ‘M’ (Merchants).</li><li>newbalanceDest: The new recipient’s balance after the transaction. Not applicable for ‘M’ (Merchants).</li><li>isFraud: Identifies transactions conducted by fraudulent agents aiming to deplete customer accounts through transfers and cash-outs.</li><li>isFlaggedFraud: Flags large-scale, unauthorized transfers between accounts, with any single transaction exceeding 200,000 being considered illegal.</li></ul><h3>What is the Fraud Analysis pipeline doing:</h3><p>The dataset referenced above is made available to us by a third party on an Azure Blob storage. Using the csv file, we will accomplish two main things:</p><ol><li>Take the csv file and load it into Snowflake for business analytics.</li><li>Take the csv file and process the data so that it can be normalized and loaded into a different Snowflake table. The normalized data will make it easy for us to use it with ML algorithms to drive outcomes such as:</li></ol><ul><li>Behavioral Analytics: By analyzing users’ behavior, businesses can detect deviations from normal patterns.</li><li>Anomaly Detection: Anomaly Detection helps in creating a baseline of normal behavior and flagging any data points that deviate significantly from it.</li><li>Identity clustering: Making a group of user identities based on common attributes and behaviors helps in identify patterns of fraudulent behavior.</li></ul><p>To keep this blog from becoming too long we will stop this pipeline at data normalization and will write a sequel to this blog to demonstrate an ML pipeline that will drive the outcomes mentioned above.</p><h3>Architecture</h3><p>The pipeline has the following architecture and will be orchestrated using Control-M.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/372/1*2BFczVz6Dl63i0iqmJPRbw.png" /></figure><p>Control-M integration plug-ins used in this architecture:</p><ul><li>Control-M Managed File Transfer to execute file movement from Amazon S3 to Azure Blob.</li><li>Control-M for Databases to load data and run queries against Snowflake.</li><li>Control-M for Kubernetes to execute python code.</li><li>Control-M for AWS Glue for ETL.</li></ul><p>See a sample of the connection profiles in the “Connection Profiles” section below.</p><p>Before setting up the Kubernetes job in the workflow below please see the details in the Kubernetes section.</p><p>Similarly before setting up the Snowflake jobs please refer to the Snowflake section in this blog.</p><h3>Workflow Summary</h3><p><strong>Blob-to-s3-transfer Job to Query Table Jobs</strong></p><ol><li><strong>Blob-to-s3-transfer Job:</strong></li></ol><ul><li><strong>Action</strong>: Transfers the data file from Azure Blob Storage to an Amazon S3 bucket.</li><li><strong>Purpose</strong>: Prepares the data for processing by moving it to a location accessible by subsequent processing jobs.</li></ul><p>2. <strong>Conditional Path:</strong></p><ul><li><strong>Branch 1: Infer Schema_Unprocessed Job<br>- </strong>Action: Executes a SQL script to infer the schema of the unprocessed data.<br><strong>-</strong> Purpose: Prepares the schema for creating a corresponding table to store the unprocessed data.<br><strong>a. Create Table_Unprocessed Job:</strong><br> <strong><em>*</em></strong> <strong>Action</strong>: Execute a SQL script to create a table in Snowflake based on the inferred schema.<br> <strong><em>*</em></strong> <strong>Purpose</strong>: Creates a structured table to store the unprocessed data for further operations.<br><strong>b.</strong> <strong>Copy Into Table_Unprocessed Job:</strong><br> <strong><em>*</em></strong> <strong>Action</strong>: Loads the unprocessed data into the newly created table in Snowflake.<br> <strong><em>*</em></strong> <strong>Purpose</strong>: Populates the table with the data that was transferred from Azure Blob Storage.<br><strong>c. Query Table_Unprocessed Job:</strong><br> <strong><em>*</em></strong> <strong>Action</strong>: Executes a SQL script to query the unprocessed data and output the results in CSV format.<br> <strong><em>*</em></strong> <strong>Purpose:</strong> Extracts and formats the data for analysis, reporting, or further processing.</li><li><strong>Branch 2: Mol-kubernetes-job<br>-</strong> <strong>Action</strong>: Executes a Kubernetes job to process the data using a Python script within a container.<br><strong>-</strong> <strong>Purpose</strong>: Processes the raw data into a more refined format, ready for further transformation or loading.<br><strong>a. Mol-glue-job</strong><br> <strong><em>*</em></strong> <strong>Action</strong>: Runs an AWS Glue job to perform ETL (Extract, Transform, Load) operations on the processed data.<br> <strong><em>*</em></strong> <strong>Purpose:</strong> Transforms the data into a structured format that can be stored and queried in Snowflake.<br><strong>b. Infer Schema Job:</strong><br> <strong><em>* </em>Action</strong>: Executes a SQL script to infer the schema of the processed data.<br> <strong><em>*</em></strong> <strong>Purpose</strong>: Prepares the schema for creating a corresponding table to store the processed data.<br><strong>c. Create Table Job: <br></strong> <strong><em>*</em></strong> <strong>Action:</strong> Executes a SQL script to create a table in Snowflake based on the inferred schema.<br> <strong><em>*</em></strong> <strong>Purpose</strong>: Creates a structured table to store the processed data for further operations.<br><strong>d. Copy Into Table Job:</strong><br> <strong><em>*</em></strong> <strong>Action:</strong> Loads the processed data into the newly created table in Snowflake.<br> <strong><em>*</em></strong> <strong>Purpose:</strong> Populates the table with the transformed data ready for analysis or reporting.<br><strong>e. Query Table Job:<br> <em>*</em> Action:</strong> Executes a SQL script to query the processed data and output the results in CSV format.<br> <strong><em>*</em></strong> <strong>Purpose:</strong> Extracts and formats the processed data for analysis, reporting, or further processing.</li></ul><h3>Orchestrating the Workflow with Control-M</h3><p>This workflow summary outlines the two possible paths the process could take, depending on whether it follows the “Infer Schema_Unprocessed” path or the “Mol-kubernets-job” path, and how each subsequent job is connected and contributes to the overall data processing and querying pipeline.</p><p>Using Control-M <strong>as the orchestration platform we get the following benefits:</strong></p><ul><li><strong>Centralized Workflow Management:</strong> Control-M provides a unified platform to orchestrate complex workflows across different systems, enabling financial institutions to manage all data processes from a single interface.</li><li><strong>End-to-End Automation:</strong> Control-M automates the execution of fraud detection workflows, reducing the need for manual intervention and ensuring that processes run efficiently and consistently.</li><li><strong>Seamless Integration:</strong> Control-M integrates with a wide range of tools and data sources, making it easier to coordinate the various components involved in fraud detection, such as File transfer processes, ETL processes, data analysis, alerting and monitoring systems.</li><li><strong>Real-Time Monitoring and Alerts:</strong> With Control-M, users can monitor the entire workflow in real-time, receiving alerts for any issues or anomalies, which is critical for maintaining the effectiveness of fraud detection systems.</li><li><strong>Compliance and Auditability:</strong> Control-M helps maintain compliance by providing detailed logs and audit trails for all data processes, ensuring that financial institutions can meet regulatory requirements.</li></ul><p>Here is what the defined workflow looks like in Control-M.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/562/1*FWNu-8k-U_voOAQsMNlDDQ.png" /></figure><p>In the next section we will go through defining each of these jobs. The jobs can defined using a drag and drop no-code approach in the Planning domain of Control-M or they can be defined as-code in JSON. For the purposes of this blog, we will use the as-code approach.</p><p>— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —</p><p><strong>Blob-to-s3-transfer Job<br></strong>Type: Job<br><strong>Action:</strong> Transfers a file from an Azure Blob storage container to an Amazon S3 bucket using the Control-M Managed File Transfer (MFT) capabilities.<br><strong>Description:</strong> This job handles the secure and automated transfer of the file “TestDataFinLogs.csv” from an Azure Blob Storage container (k8s-container) to a designated folder in an S3 bucket (mol-preprocessed-data). The file is renamed during the transfer process to “mol-raw-data.csv” at the destination.<br><strong>Dependencies:</strong> Triggers two subsequent events after the transfer: Blob-to-s3-transfer-TO-mol-kubernets-job and Blob-to-s3-transfer-TO-Infer_Schema_Unprocessed, enabling downstream jobs to start once the file transfer is completed.</p><p><strong>Key Configuration Details:</strong></p><ul><li>Source Connection: AZSMB_BLOB profile, accessing the Azure Blob Storage container k8s-container.</li><li>Destination Connection: MFTS3 profile, targeting the S3 bucket <em>mol-preprocessed-data</em>.</li><li>File Name Handling: The source file name “TestDataFinLogs.csv” is replaced with “mol-raw-data.csv” in the destination S3 bucket.</li><li>File Watcher: The job includes a file watcher that monitors the source file for changes, ensuring that the transfer occurs when the file is ready.</li></ul><p><strong>See an example in the figure below:</strong></p><pre>&quot;Blob-to-s3-transfer&quot;: {<br>  &quot;Type&quot;: &quot;Job:FileTransfer&quot;,<br>  &quot;ConnectionProfileSrc&quot;: &quot;AZSMB_BLOB&quot;,<br>  &quot;ConnectionProfileDest&quot;: &quot;MFTS3&quot;,<br>  &quot;S3BucketNameDest&quot;: &quot;mol-preprocessed-data&quot;,<br>  &quot;AzureContainerNameSrc&quot;: &quot;k8s-container&quot;,<br>  &quot;Host&quot;: “&lt;insert Host IP Address&gt;“,<br>  &quot;CreatedBy&quot;: “&lt;creator’s email automatically generated&gt;“,<br>  &quot;RunAs&quot;: &quot;AZSMB_BLOB+MFTS3&quot;,<br>  &quot;Variables&quot;: [<br>    {&quot;FTP-LOSTYPE&quot;: &quot;Unix&quot;},<br>    {&quot;FTP-CONNTYPE1&quot;: &quot;Azure&quot;},<br>    {&quot;FTP-ROSTYPE&quot;: &quot;Unix&quot;},<br>    {&quot;FTP-CONNTYPE2&quot;: &quot;S3&quot;},<br>    {&quot;FTP-CM_VER&quot;: &quot;9.0.00&quot;},<br>    {&quot;FTP-OVERRIDE_WATCH_INTERVAL1&quot;: &quot;0&quot;}<br>  ],<br>  &quot;FileTransfers&quot;: [<br>    {<br>      &quot;TransferType&quot;: &quot;Binary&quot;,<br>      &quot;TransferOption&quot;: &quot;SrcToDestFileWatcher&quot;,<br>      &quot;Src&quot;: &quot;/TestDataFinLogs.csv&quot;,<br>      &quot;Dest&quot;: &quot;/input/&quot;,<br>      &quot;ABSTIME&quot;: &quot;0&quot;,<br>      &quot;TIMELIMIT&quot;: &quot;0&quot;,<br>      &quot;UNIQUE&quot;: &quot;0&quot;,<br>      &quot;SRCOPT&quot;: &quot;0&quot;,<br>      &quot;IF_EXIST&quot;: &quot;0&quot;,<br>      &quot;DSTOPT&quot;: &quot;0&quot;,<br>      &quot;RECURSIVE&quot;: &quot;0&quot;,<br>      &quot;EXCLUDE_WILDCARD&quot;: &quot;0&quot;,<br>      &quot;TRIM&quot;: &quot;1&quot;,<br>      &quot;NULLFLDS&quot;: &quot;0&quot;,<br>      &quot;VERNUM&quot;: &quot;0&quot;,<br>      &quot;CASEIFS&quot;: &quot;0&quot;,<br>      &quot;FileWatcherOptions&quot;: {<br>        &quot;AssignFileNameToVariable&quot;: &quot;TestDataFinLogs&quot;,<br>        &quot;VariableType&quot;: &quot;Global&quot;,<br>        &quot;UnitsOfTimeLimit&quot;: &quot;Minutes&quot;<br>      },<br>      &quot;IncrementalTransfer&quot;: {<br>        &quot;IncrementalTransferEnabled&quot;: false,<br>        &quot;MaxModificationAgeForFirstRunEnabled&quot;: false,<br>        &quot;MaxModificationAgeForFirstRunInHours&quot;: &quot;1&quot;<br>      },<br>      &quot;DestinationFilename&quot;: {<br>        &quot;FindSubString&quot;: &quot;TestDataFinLogs.csv&quot;,<br>        &quot;ReplaceSubString&quot;: &quot;mol-raw-data.csv&quot;,<br>        &quot;ModifyCase&quot;: &quot;No&quot;<br>      }<br>    }<br>  ],<br>  &quot;When&quot;: {<br>    &quot;WeekDays&quot;: [&quot;NONE&quot;],<br>    &quot;MonthDays&quot;: [&quot;ALL&quot;],<br>    &quot;DaysRelation&quot;: &quot;OR&quot;<br>  },<br>  &quot;eventsToAdd&quot;: {<br>    &quot;Type&quot;: &quot;AddEvents&quot;,<br>    &quot;Events&quot;: [<br>      {&quot;Event&quot;: &quot;Blob-to-s3-transfer-TO-mol-kubernets-job&quot;},<br>      {&quot;Event&quot;: &quot;Blob-to-s3-transfer-TO-Infer_Schema_Unprocessed&quot;}<br>    ]<br>  }<br>}</pre><h3>BRANCH 1 WORKFLOW SECTION</h3><p><strong>Infer Schema_Unprocessed Job</strong><br><strong>Type: </strong>Job:Database</p><p><strong>Action:</strong> Executes a SQL script on Snowflake to infer the schema of unprocessed data, preparing it for further processing or table creation.<br><strong>Description:</strong> This job runs an SQL script located at /home/ctmagent/snowflake_sql/infer_schema2.sql using a Snowflake JDBC connection. The script infers the schema for a dataset that has not yet been processed, setting the stage for the subsequent creation of a corresponding table in Snowflake.<br><strong>Dependencies:</strong> The job waits for the event <em>Blob-to-s3-transfer-TO-Infer_Schema_Unprocessed</em>, ensuring that the data transfer from Azure Blob Storage to S3 is complete before attempting to infer the schema. Upon successful execution, it triggers the event <em>Infer_Schema_Unprocessed-TO-Create_Table_Unprocessed</em>, indicating that the schema has been inferred and is ready for table creation.</p><p><strong>Key Configuration Details:</strong></p><ul><li><strong>SQL Script:<br></strong><em>USE DATABASE AUTO_DEMO_DB;<br>USE SCHEMA PUBLIC;<br>USE WAREHOUSE DEMO_WH;<br>USE ROLE SYSADMIN;<br> <br>SELECT *<br> FROM TABLE(<br> </em>INFER_SCHEMA(<br> LOCATION=&gt;’<a href="http://twitter.com/prefraudstage/mol-raw-data">@prefraudstage/mol-raw-data</a>.csv’<br> , FILE_FORMAT=&gt;’fraud_format’<br> , IGNORE_CASE=&gt;TRUE<br> )<br> );</li></ul><p><strong>See an example in the figure below:</strong></p><pre>&quot;Infer Schema_Unprocessed&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/infer_schema2.sql&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Blob-to-s3-transfer-TO-Infer_Schema_Unprocessed&quot;<br>        } ]<br>      },<br>      &quot;eventsToAdd&quot; : {<br>        &quot;Type&quot; : &quot;AddEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Infer_Schema_Unprocessed-TO-Create_Table_Unprocessed&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Blob-to-s3-transfer-TO-Infer_Schema_Unprocessed&quot;<br>        } ]<br>      }<br>    }</pre><p><strong>Create Table_Unprocessed Job</strong><br><strong>Type:</strong> Job:Database</p><p><strong>Action:</strong> Executes a SQL script on Snowflake to create a table for unprocessed data, based on the schema inferred in a previous step.<br><strong>Description:</strong> This job runs a SQL script located at /home/ctmagent/snowflake_sql/create_table2.sql using a Snowflake JDBC connection. The script creates a new table in Snowflake, designed to hold unprocessed data, with its structure based on the schema that was inferred in an earlier job.<br><strong>Dependencies:</strong> The job waits for the event <em>Infer_Schema_Unprocessed-TO-Create_Table_Unprocessed</em>, ensuring that the schema inference is complete before attempting to create the table. Upon successful execution, it triggers the event <em>Create_Table_Unprocessed-TO-Copy_Into_Table_Unprocessed</em>, signaling that the table is ready for data to be loaded.<br><strong>Key Configuration Details:</strong></p><ul><li><strong>SQL Script<br></strong>CREATE OR REPLACE TABLE presamtable<br> USING TEMPLATE (<br> SELECT ARRAY_AGG(OBJECT_CONSTRUCT(*))<br> FROM TABLE(<br> INFER_SCHEMA(<br> LOCATION=&gt;’<a href="http://twitter.com/prefraudstage/mol-raw-data">@prefraudstage/mol-raw-data</a>.csv’,<br> FILE_FORMAT=&gt;’fraud_format’<br> )<br> ));</li></ul><p><strong>See an example in the figure below:</strong></p><pre>&quot;Create Table_Unprocessed&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/create_table2.sql&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Infer_Schema_Unprocessed-TO-Create_Table_Unprocessed&quot;<br>        } ]<br>      },<br>      &quot;eventsToAdd&quot; : {<br>        &quot;Type&quot; : &quot;AddEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Create_Table_Unprocessed-TO-Copy_Into_Table_Unprocessed&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Infer_Schema_Unprocessed-TO-Create_Table_Unprocessed&quot;<br>        } ]<br>      }<br>    }</pre><p><strong>Copy Into Table_Unprocessed Job</strong><br><strong>Type:</strong> Job:Database</p><p><strong>Action:</strong> Executes a SQL script on Snowflake to copy data into a table that was created for unprocessed data.<br><strong>Description: </strong>This job runs a SQL script located at /home/ctmagent/snowflake_sql/copy_data2.sql using a Snowflake JDBC connection. The script copies data into the unprocessed table that was created in a previous step, populating the table with the data that is ready for further processing or analysis.<br><strong>Dependencies:</strong> The job waits for the event <em>Create_Table_Unprocessed-TO-Copy_Into_Table_Unprocessed</em>, ensuring that the table creation is complete before attempting to load data into it. Upon successful execution, it triggers the event <em>Copy_Into_Table_Unprocessed-TO-Query_Table_Unprocessed</em>, signaling that the data has been loaded and the table is ready for querying.</p><p><strong>Key Configuration Details:<br>• SQL Script:<br></strong>COPY INTO presamtable FROM <a href="http://twitter.com/prefraudstage/mol-raw-data">@prefraudstage/mol-raw-data</a>.csv<br> FILE_FORMAT = (<br> FORMAT_NAME= ‘fraud_format’<br> )<br> MATCH_BY_COLUMN_NAME=CASE_INSENSITIVE;</p><p><strong>See an example in the figure below:</strong></p><pre>&quot;Copy Into Table_Unprocessed&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/copy_data2.sql&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Create_Table_Unprocessed-TO-Copy_Into_Table_Unprocessed&quot;<br>        } ]<br>      },<br>      &quot;eventsToAdd&quot; : {<br>        &quot;Type&quot; : &quot;AddEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Copy_Into_Table_Unprocessed-TO-Query_Table_Unprocessed&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Create_Table_Unprocessed-TO-Copy_Into_Table_Unprocessed&quot;<br>        } ]<br>      }<br>    }</pre><p><strong>Query Table_Unprocessed Job</strong><br><strong>Type:</strong> Job:Database</p><p><strong>Action:</strong> Executes a SQL script on Snowflake to query data from an unprocessed data table and outputs the results in CSV format.<br><strong>Description:</strong> This job runs a SQL script located at /home/ctmagent/snowflake_sql/query_data2.sql using a Snowflake JDBC connection. The script queries data from the unprocessed table and outputs the query results in CSV format, enabling further analysis or processing.<br><strong>Dependencies:</strong> The job waits for the event <em>Copy_Into_Table_Unprocessed-TO-Query_Table_Unprocessed</em>, ensuring that the data has been successfully loaded into the table before querying it. Upon successful execution, the job outputs the query results in the specified format.<br><strong>Key Configuration Details:</strong></p><ul><li><strong>SQL Script:<br></strong><em>select * FROM presamtable;</em></li></ul><p><strong>See an example in the figure below:</strong></p><pre>&quot;Query Table_Unprocessed&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLOutputFormat&quot; : &quot;CSV&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/query_data2.sql&quot;,<br>      &quot;OutputSQLOutput&quot; : &quot;Y&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Copy_Into_Table_Unprocessed-TO-Query_Table_Unprocessed&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Copy_Into_Table_Unprocessed-TO-Query_Table_Unprocessed&quot;<br>        } ]<br>      }<br>    }</pre><h3>PROCESSED DATA WORKFLOW SECTION</h3><p><strong>Mol-Kubernetes-job</strong></p><p><strong>Type:</strong> Job</p><p><strong>Action:</strong> Executes a Kubernetes job that runs a data processing task within a Kubernetes cluster.<br><strong>Description:</strong> This job uses Kubernetes to run a specific data processing task defined in a Kubernetes job specification YAML. The job pulls an image from an AWS ECR repository and executes a Python script to process data from an S3 bucket. After the job completes, it automatically retrieves the pod logs and cleans up the Kubernetes job by deleting it.<br><strong>Dependencies:</strong> The job waits for the event <em>Blob-to-s3-transfer-TO-mol-kubernets-job</em>, ensuring that the necessary data has been transferred from Azure Blob Storage to the S3 bucket before the Kubernetes job starts processing.<br><strong>Key Configuration Details:</strong></p><ul><li>• <strong>Job Specification YAML:</strong> The Kubernetes job is defined in a YAML specification, which includes:<br>- Container Name: data-processing-container<br>- Image: Pulled from 623469066856.dkr.ecr.us-west-2.amazonaws.com/new-mol-kubernetes-plugin-repo:latest<br>- Command: Executes the Python script main.py with specified arguments to process data.<br>- Restart Policy: Set to Never to prevent the job from restarting automatically.</li><li><strong>Connection Profile: </strong>The job uses the MOL-K8S-CONNECTION-PROFILE to connect to the Kubernetes cluster and execute the job.</li><li><strong>Pod Logs:</strong> Configured to automatically retrieve logs after the job runs (Get Pod Logs: Get Logs).</li><li><strong>Job Cleanup:</strong> The Kubernetes job is deleted after completion to ensure resources are freed (Job Cleanup: Delete Job).</li></ul><p><strong>Event Handling:</strong></p><ul><li><strong>Events to Wait For:<br>- </strong>The job waits for the event <em>Blob-to-s3-transfer-TO-mol-kubernets-job</em>, ensuring the data is available in S3 before the Kubernetes job starts.</li><li>Events to Trigger:<br>- After successfully processing the data, the job triggers the event mol-<em>kubernets-job-TO-mol-glue-job</em>, signaling that the data processing is complete, and the next step (likely data transformation or loading) can begin.</li></ul><p><strong>Mol-glue-job</strong></p><p><strong>For details on how to setup Control-M with AWS glue see the Snowflake Setup section below</strong></p><p><strong>Type:</strong> Job</p><p><strong>Action:</strong> Executes an AWS Glue job to process financial data as part of a broader ETL workflow.<br><strong>Description: </strong>This job runs an AWS Glue job named mol-financial-data-processing, which is responsible for processing financial data. AWS Glue is used to perform ETL (Extract, Transform, Load) operations, transforming raw data into a structured format suitable for further analysis or storage. The job is triggered automatically after the completion of a preceding Kubernetes job.<br><strong>Dependencies:</strong> The job waits for the event <em>mol-kubernets-job-TO-mol-glue-job</em>, ensuring that the data processing task handled by Kubernetes is complete before starting the AWS Glue job.<br><strong>Key Configuration Details:</strong></p><ul><li><strong>Glue Job Name:</strong> The AWS Glue job executed by this task is mol-financial-data-processing.</li><li><strong>Connection Profile:</strong> The job uses the MOLGLUECONNECTIONPROFILE to connect to AWS Glue and run the job.</li></ul><p><strong>Event Handling:</strong></p><ul><li><strong>Events to Wait For:</strong><br>- The job waits for the event <em>mol-kubernets-job-TO-mol-glue-job</em>, ensuring the Kubernetes data processing is finished before starting the Glue job.</li><li><strong>Events to Trigger:</strong><br>- After successfully completing the Glue job, it triggers the event <em>mol-glue-job-TO-Infer_Schema</em>, signaling that the data processing is complete, and the schema inference step can begin.</li></ul><p><strong>Infer Schema Job (Processed Data)</strong></p><p><strong>Type:</strong> Job:Database</p><p><strong>Action:</strong> Executes a SQL script on Snowflake to infer the schema of a dataset, preparing the data for subsequent processing.<br><strong>Description: </strong>This job runs a SQL script located at /home/ctmagent/snowflake_sql/infer_schema.sql using a Snowflake JDBC connection. The script infers the schema of a dataset, typically in preparation for creating a corresponding table in Snowflake.<br><strong>Dependencies:</strong> The job waits for the event <em>mol-glue-job-TO-Infer_Schema</em>, ensuring that a prior data processing step is completed before attempting to infer the schema. Upon successful completion, it triggers the event <em>Infer_Schema-TO-Create_Table</em>, signaling that the inferred schema is ready for use in table creation.<br><strong>Key Configuration Details:</strong></p><ul><li><strong>SQL Script:</strong><br><em>USE DATABASE AUTO_DEMO_DB;<br>USE SCHEMA PUBLIC;<br>USE WAREHOUSE DEMO_WH;<br>USE ROLE SYSADMIN;<br>SELECT *<br> FROM TABLE(<br> INFER_SCHEMA(<br> LOCATION=&gt;’</em><a href="http://twitter.com/fraudstage/glue-output"><em>@fraudstage/glue-output</em></a><em>.csv’<br> , FILE_FORMAT=&gt;’fraud_format’<br> , IGNORE_CASE=&gt;TRUE<br> )<br> );</em></li></ul><p><strong>See an example in the figure below:</strong></p><pre>&quot;Infer Schema&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/infer_schema.sql&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;mol-glue-job-TO-Infer_Schema&quot;<br>        } ]<br>      },<br>      &quot;eventsToAdd&quot; : {<br>        &quot;Type&quot; : &quot;AddEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Infer_Schema-TO-Create_Table&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;mol-glue-job-TO-Infer_Schema&quot;<br>        } ]<br>      }<br>    }<br><br></pre><p><strong>Create Table Job<br>Type:</strong> Job:Database</p><p><strong>Action: </strong>Executes a SQL script on Snowflake to create a table based on a previously inferred schema.<br><strong>Description:</strong> This job runs a SQL script located at /home/ctmagent/snowflake_sql/create_table.sql using a Snowflake JDBC connection. The script creates a new table in Snowflake, structured according to the schema that was inferred in a prior step. This table is prepared to store data that will be loaded in subsequent steps of the workflow. The job uses the SNOWFLAKE_JDBC connection profile to connect to Snowflake and execute the SQL script.<br><strong>Dependencies:</strong> The job waits for the event <em>Infer_Schema-TO-Create_Table</em>, ensuring that the schema inference process is complete before attempting to create the table. Upon successful execution, it triggers the event <em>Create_Table-TO-Copy_Into_Table</em>, indicating that the table is ready for data to be loaded.<br><strong>Key Configuration Details:</strong></p><ul><li>SQL Script:<br>USE DATABASE AUTO_DEMO_DB;<br>USE SCHEMA PUBLIC;<br>USE WAREHOUSE DEMO_WH;<br>USE ROLE SYSADMIN;<br>CREATE OR REPLACE TABLE final_table<br> USING TEMPLATE (<br> SELECT ARRAY_AGG(OBJECT_CONSTRUCT(*))<br> FROM TABLE(<br> INFER_SCHEMA(<br> LOCATION=&gt;’<a href="http://twitter.com/fraudstage/glue-output">@fraudstage/glue-output</a>.csv’,<br> FILE_FORMAT=&gt;’fraud_format’<br> )<br> ));</li></ul><p>See an example in the figure below:</p><pre>&quot;Create Table&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/create_table.sql&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Infer_Schema-TO-Create_Table&quot;<br>        } ]<br>      },<br>      &quot;eventsToAdd&quot; : {<br>        &quot;Type&quot; : &quot;AddEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Create_Table-TO-Copy_Into_Table&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Infer_Schema-TO-Create_Table&quot;<br>        } ]<br>      }<br>    }</pre><p><strong>Copy Into Table Job</strong><br><strong>Type:</strong> Job:Database</p><p><strong>Action:</strong> Executes a SQL script on Snowflake to load data into a newly created table.<br><strong>Description:</strong> This job runs a SQL script located at /home/ctmagent/snowflake_sql/copy_data.sql using a Snowflake JDBC connection. The script copies or loads data into a table that was previously created in the workflow, making the data available for subsequent querying or processing steps.<br><strong>Dependencies: </strong>The job waits for the event Create_Table-TO-Copy_Into_Table, ensuring that the table has been successfully created before attempting to load data into it. Upon successful execution, it triggers the event Copy_Into_Table-TO-Query_Table, indicating that the data is now loaded and ready for querying.<br><strong>Key Configuration Details:</strong></p><ul><li>SQL Script:<br>USE DATABASE AUTO_DEMO_DB;<br>USE SCHEMA PUBLIC;<br>USE WAREHOUSE DEMO_WH;<br>USE ROLE SYSADMIN;<br>COPY INTO final_table FROM <a href="http://twitter.com/fraudstage/glue-output">@fraudstage/glue-output</a>.csv<br> FILE_FORMAT = (<br> FORMAT_NAME= ‘fraud_format’<br> )<br> MATCH_BY_COLUMN_NAME=CASE_INSENSITIVE;</li></ul><p><strong>See an example in the figure below:</strong></p><pre>&quot;Copy Into Table&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/copy_data.sql&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Create_Table-TO-Copy_Into_Table&quot;<br>        } ]<br>      },<br>      &quot;eventsToAdd&quot; : {<br>        &quot;Type&quot; : &quot;AddEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Copy_Into_Table-TO-Query_Table&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Create_Table-TO-Copy_Into_Table&quot;<br>        } ]<br>      }<br>    }</pre><p><strong>Query Table Job<br>Type:</strong> Job:Database</p><p><strong>Action: </strong>Executes a SQL script on Snowflake to query data from a table and output the results in CSV format.<br><strong>Description:</strong> This job runs a SQL script located at /home/ctmagent/snowflake_sql/query_data.sql using a Snowflake JDBC connection. The script queries data from a previously populated table, and the results are output in CSV format. This allows for easy analysis, reporting, or further processing of the queried data.<br><strong>Dependencies: </strong>The job waits for the event Copy_Into_Table-TO-Query_Table, ensuring that data has been successfully loaded into the table before attempting to run the query. Upon completion, it handles the necessary event management to maintain workflow integrity.<br><strong>Key Configuration Details:</strong></p><ul><li><strong>SQL Script:<br></strong>USE DATABASE AUTO_DEMO_DB;<br>USE SCHEMA PUBLIC;<br>USE WAREHOUSE DEMO_WH;<br>USE ROLE SYSADMIN;<br>select * FROM final_table;</li></ul><p><strong>See an example in the figure below:</strong></p><pre>&quot;Query Table&quot; : {<br>      &quot;Type&quot; : &quot;Job:Database:SQLScript&quot;,<br>      &quot;ConnectionProfile&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;SQLOutputFormat&quot; : &quot;CSV&quot;,<br>      &quot;SQLScript&quot; : &quot;/home/ctmagent/snowflake_sql/query_data.sql&quot;,<br>      &quot;OutputSQLOutput&quot; : &quot;Y&quot;,<br>      &quot;Host&quot; : “&lt;insert Host IP Address&gt;“,<br>      &quot;CreatedBy&quot; : “&lt;creator’s email automatically generated&gt;“,<br>      &quot;RunAs&quot; : &quot;SNOWFLAKE_JDBC&quot;,<br>      &quot;When&quot; : {<br>        &quot;WeekDays&quot; : [ &quot;NONE&quot; ],<br>        &quot;MonthDays&quot; : [ &quot;ALL&quot; ],<br>        &quot;DaysRelation&quot; : &quot;OR&quot;<br>      },<br>      &quot;eventsToWaitFor&quot; : {<br>        &quot;Type&quot; : &quot;WaitForEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Copy_Into_Table-TO-Query_Table&quot;<br>        } ]<br>      },<br>      &quot;eventsToDelete&quot; : {<br>        &quot;Type&quot; : &quot;DeleteEvents&quot;,<br>        &quot;Events&quot; : [ {<br>          &quot;Event&quot; : &quot;Copy_Into_Table-TO-Query_Table&quot;<br>        } ]<br>      }<br>    }</pre><p>This workflow summary outlines the two possible paths the process could take, depending on whether it follows the “Infer Schema_Unprocessed” path or the “Mol-kubernets-job” path, and how each subsequent job is connected and contributes to the overall data processing and querying pipeline.</p><h3>Workflow Execution</h3><p>Once the workflow is setup in Control-M it can be executed by an event or a schedule. Included below are some screenshots of the workflow from the Monitoring Domain in Control-M.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/689/1*13YC7S0HE7JTfpRZpoV25w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*MriSsXZyS1tbdAVWJ8hzhg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/730/1*Q6y54YnrM1nbP-TPcW7qyQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/703/1*hDb_94qrbsDMI0G4CbW79Q.png" /></figure><h3><strong>Kubernetes Solution Setup</strong></h3><p>In our fraud analysis workflow, deploying a Kubernetes pod to handle data preprocessing is a crucial step. This pod will run a Python script that the raw data in S3, preparing it for further ETL operations and analysis. Below, we’ll discuss the specifics of the pod deployment, the Docker image used, and the Python script’s functionality in the data preprocessing stage.</p><h4>Deploying the Pod in Kubernetes</h4><p>As part of our Kubernetes setup, we deploy a pod that will execute the Python script responsible for preprocessing raw data. This process is automated within the Kubernetes environment, ensuring scalability and efficiency.</p><p><strong>Prerequisites<br></strong>Before diving into the Kubernetes and AWS Glue setup, ensure that you have the following prerequisites in place:</p><ul><li>Control-M Environment Deployed within an EKS cluster or any other Kubernetes environment of your choice.</li><li>Control-M Agent with Kubernetes : Control-M</li><li>AWS S3 Bucket: For storing raw and processed data.</li><li>AWS Glue Service: Configured for ETL processes.</li><li>Docker and Kubernetes: Set up for containerization and orchestration of the preprocessing tasks.</li><li>Amazon ECR (Elastic Container Registry): For storing Docker images used in the Kubernetes pods.</li></ul><p><strong>Step 1 : Create the Amazon ECR Repository<br></strong>Since we are using Amazon ECR to store our Docker images, the first step is to create an ECR repository.</p><p><strong>Create ECR Repository:<br> — </strong>Use the AWS CLI to create a new ECR repository where you’ll push your Docker images. <br> — Take note of the repository URI returned by this command, as you’ll need it for the Docker image push process.</p><pre>aws ecr create-repository --repository-name &lt;Enter Repository Name&gt; --region us-west-2</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*g2o2MQavYY6J6rJaAsYw_Q.png" /></figure><p><strong>Step 2: Prepare the Application Files <br></strong>Your Docker image will include the following essential files.</p><p><strong>Dockerfile:</strong></p><pre># Use the official Python image from Docker Hub<br>FROM python:3.9-slim<br><br># Set the working directory in the container<br>WORKDIR /app<br><br># Copy the requirements file into the container<br>COPY requirements.txt .<br><br># Install the necessary dependencies<br>RUN pip install --no-cache-dir -r requirements.txt<br><br># Copy the rest of your application code into the container<br>COPY . .<br># Specify the command to run your script with input and output paths<br>CMD [&quot;python3&quot;, &quot;/app/main.py&quot;, &quot;-b&quot;, &quot;mol-preprocessed-data&quot;, &quot;-i&quot;, &quot;input/mol-raw-data.csv&quot;, &quot;-o&quot;, &quot;output/output.csv&quot;]<br></pre><p>The Dockerfile is responsible for setting up the environment in which the Python script will run.</p><p>Base Image: The image is based on Python 3.9 slim, which is a lightweight version of Python suitable for our needs.<br>Working Directory: The working directory inside the container is set to /app.</p><p>Dependencies: The dependencies listed in requirements.txt are installed.</p><p>Copy Files: The application code is copied into the container.</p><p>Execution Command: The command to run the Python script with the necessary input and output paths is specified.</p><p><strong>requirements.txt:<br></strong>This file lists the Python packages required by the script:<br>These dependencies are crucial for data processing, interaction with S3, and other data processing operations.</p><pre>pandas<br>boto3<br>numpy<br>scikit-learn</pre><p><strong>python Script (main.py):</strong></p><pre>import pandas as pd<br>from sklearn.preprocessing import MinMaxScaler, LabelEncoder<br>import argparse<br>import boto3<br><br>def preprocess_data(input_file, output_file):<br>    # Load the data<br>    data = pd.read_csv(input_file)<br><br>    # Handle missing values<br>    data = data.dropna()<br><br>    # Remove duplicates<br>    data = data.drop_duplicates()<br><br>    # Standardize column names<br>    data.columns = [col.lower() for col in data.columns]<br><br>    # Convert columns to appropriate data types<br>    data[&#39;amount&#39;] = data[&#39;amount&#39;].astype(float)<br>    data[&#39;oldbalanceorg&#39;] = data[&#39;oldbalanceorg&#39;].astype(float)<br>    data[&#39;newbalanceorig&#39;] = data[&#39;newbalanceorig&#39;].astype(float)<br><br>    # Create new features<br>    data[&#39;balance_difference&#39;] = data[&#39;oldbalanceorg&#39;] - data[&#39;newbalanceorig&#39;]<br><br>    # Filter irrelevant data (example: remove rows where amount is zero)<br>    data = data[data[&#39;amount&#39;] &gt; 0]<br><br>    # Normalize/scale numerical features (example: Min-Max Scaling)<br>    scaler = MinMaxScaler()<br>    data[[&#39;amount&#39;, &#39;oldbalanceorg&#39;, &#39;newbalanceorig&#39;, &#39;balance_difference&#39;]] = scaler.fit_transform(<br>        data[[&#39;amount&#39;, &#39;oldbalanceorg&#39;, &#39;newbalanceorig&#39;, &#39;balance_difference&#39;]]<br>    )<br><br>    # Encode categorical variables (example: Label Encoding)<br>    label_encoder = LabelEncoder()<br>    data[&#39;type&#39;] = label_encoder.fit_transform(data[&#39;type&#39;])<br>    data[&#39;nameorig&#39;] = label_encoder.fit_transform(data[&#39;nameorig&#39;])<br>    data[&#39;namedest&#39;] = label_encoder.fit_transform(data[&#39;namedest&#39;])<br><br>    # Save the preprocessed data<br>    data.to_csv(output_file, index=False)<br><br>def download_from_s3(bucket_name, s3_file, local_file):<br>    s3 = boto3.client(&#39;s3&#39;)<br>    s3.download_file(bucket_name, s3_file, local_file)<br><br>def upload_to_s3(local_file, bucket_name, s3_file):<br>    s3 = boto3.client(&#39;s3&#39;)<br>    try:<br>        s3.upload_file(local_file, bucket_name, s3_file)<br>        print(f&quot;Upload Successful: {local_file} to s3://{bucket_name}/{s3_file}&quot;)<br>    except Exception as e:<br>        print(f&quot;Upload Failed: {e}&quot;)<br><br>if __name__ == &quot;__main__&quot;:<br>    parser = argparse.ArgumentParser(description=&quot;Data preprocessing script.&quot;)<br>    parser.add_argument(&quot;-b&quot;, &quot;--bucket&quot;, required=True, help=&quot;S3 bucket name&quot;)<br>    parser.add_argument(&quot;-i&quot;, &quot;--input&quot;, required=True, help=&quot;Input S3 file path&quot;)<br>    parser.add_argument(&quot;-o&quot;, &quot;--output&quot;, required=True, help=&quot;Output S3 file path&quot;)<br><br>    args = parser.parse_args()<br><br>    local_input_file = &#39;/tmp/input.csv&#39;<br>    local_output_file = &#39;/tmp/output.csv&#39;<br><br>    # Download input file from S3<br>    download_from_s3(args.bucket, args.input, local_input_file)<br><br>    # Preprocess data<br>    preprocess_data(local_input_file, local_output_file)<br><br>    # Upload output file to S3<br>    upload_to_s3(local_output_file, args.bucket, args.output)</pre><p>This script performs the data preprocessing tasks necessary for the fraud detection workflow. This is central to the data preprocessing stage in our fraud detection workflow. Here is a detailed breakdown of the script’s functionality.</p><ol><li><strong>Input Data Handling:<br>* </strong>The script starts by downloading raw data from an S3 bucket using the download_from_s3 function. The raw data is then loaded into a pandas DataFrame for processing.</li><li><strong>Data Cleaning:<br>*</strong> Handling Missing Values: The script removes any rows with missing values to ensure data quality.<br><strong>*</strong> Removing Duplicates: Duplicate records are also removed to prevent any data redundancy.<br><strong>*</strong> Standardizing Column Names: Column names are converted to lowercase to maintain consistency.</li><li><strong>Feature Engineering:<br>* </strong>Creating New Features: A new feature, balance_difference, is calculated to capture the difference between oldbalanceorg and newbalanceorig. This feature is crucial for detecting discrepancies that might indicate fraudulent activity.</li><li><strong>Data Filtering:<br>*</strong> The script filters out any records where the amount is zero, as these are not relevant to the fraud detection process.</li><li><strong>Data Transformation:<br>* </strong>Normalization: Numerical features are normalized using MinMaxScaler to scale them between 0 and 1, ensuring that different features contribute equally to the analysis.<br><strong>* </strong>Label Encoding: Categorical variables like type, nameorig, and namedest are encoded using LabelEncoder to convert them into a numerical format suitable for machine learning models.</li><li>Output Data Handling:<br><strong>* </strong>After preprocessing, the script saves the cleaned and processed data to a local file. This file is then uploaded back to the S3 bucket using the upload_to_s3 function, making it available for subsequent processing stages in AWS Glue and Snowflake.</li></ol><p><strong>kubernetes YAML file:<br></strong>The YAML file defines the Kubernetes job that the container will execute when the pod is run. This job is essential because it specifies how the Python script should be executed within the Kubernetes environment. Control-M will trigger this pod, ensuring that the job runs to completion.</p><pre>apiVersion: batch/v1<br>kind: Job<br>metadata:<br>  name: data-processing-pod<br>spec:<br>  template:<br>    spec:<br>      containers:<br>      - name: data-processing-container<br>        image: &lt;account-id&gt;.dkr.ecr.us-west-2.amazonaws.com/new-mol-kubernetes-plugin-repo:latest<br>        command: [&quot;/bin/sh&quot;, &quot;-c&quot;, &quot;python3 /app/main.py -b mol-preprocessed-data -i input/mol-raw-data.csv -o output/output.csv &amp;&amp; sleep 300&quot;]<br>      restartPolicy: Never</pre><p><strong>Image:</strong> Specifies the Docker image stored in ECR that contains the Python script and its dependencies.<br><strong>Command:</strong> Details the command that runs the Python script with the necessary arguments, ensuring that the data is processed as required.<br><strong>Restart Policy: </strong>Set to Never, indicating that the job will not restart after completion.</p><p><strong>Step 3: Building and pushing the Docker Image to ECR<br></strong>Next, we need to package the Python script into a Docker image, build the image locally, and then push it to the newly created ECR repository.</p><p><strong>Authenticate Docker to ECR:</strong> Authenticate your Docker client to the ECR registry so you can push images.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0jVVhMH_yp32VZLr19YB5Q.png" /></figure><p><strong>Build the Docker Image:</strong> Navigate to the directory containing your Dockerfile and build the Docker image:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/931/1*M46YRyVD0VAK3sJA-KoRpQ.png" /></figure><p><strong>Tag the Docker Image:</strong> Tag your Docker image with the ECR repository URI:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ocn_-YzcGhec49EC4mwEuQ.png" /></figure><p><strong>Push the Docker Image to ECR:</strong> Push the Docker image to your ECR repository:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Y4xLiGcT1TkJYVz2e3cLEA.png" /></figure><p><strong>With the Docker image pushed to ECR, it’s now ready to be used in the Kubernetes job that handles the data preprocessing.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*60C908O7uBfQ6Ci7M8zBFA.png" /></figure><h3>Snowflake Setup:</h3><p>Given that the data has already been extracted, transformed, and loaded into Snowflake using Kubernetes and AWS Glue, our focus with Snowflake is now on querying the transformed data to detect fraudulent activities. Here’s how you can leverage Snowflake’s capabilities for this purpose:</p><ol><li><strong>Set Up Your Snowflake Environment: </strong>Ensure that your transformed data is properly loaded into Snowflake tables. Verify the table schemas and data quality to ensure that all necessary data points are available for querying.</li><li><strong>Run Queries to Identify Fraudulent Transactions: </strong>In this demo, we only ran one query to display all the contents of the transformed table.</li></ol><p>To begin, create a Snowflake <a href="https://docs.snowflake.com/en/sql-reference/sql/create-database">database</a>, <a href="https://docs.snowflake.com/en/sql-reference/sql/create-schema">schema</a>, <a href="https://docs.snowflake.com/en/sql-reference/sql/create-role">role</a>, 2 stages* and <a href="https://docs.snowflake.com/en/sql-reference/sql/create-warehouse">warehouse</a>.</p><p>2 different stages (Fraudstage and Prefraudstage) were created in this scenario to house both the unprocessed data and the processed, transformed data.</p><p><em>*Snowflake stages are locations where data files are stored (staged) for loading and unloading data. See a screenshot of the 2 Snowflake stages that attach the S3 bucket to the Snowflake profile below.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/529/1*yyJIgp85Eql-AdSx6U03vg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/529/1*2NXdz0c-yrm-BqyhSDDdIg.png" /></figure><p><strong>Best practices and considerations for Snowflake implementation:</strong></p><ul><li>Make use of Snowflake stages when loading data from an external system using Control-M. Control-M transfer jobs like the first one we created in this demo (S3_Object_Transfer) require a Snowflake stage be set up. Stages generally make it much easier to repeatedly load data in a specific format.</li><li>Use the “SYSADMIN” role for most of your Snowflake job processes within Control-M. This has a few benefits:<br>- <strong>Security and principle of least privilege:</strong> The Account Admin role has the highest level of access within a Snowflake account, including the ability to manage users and roles, billing, and account settings. Using Sysadmin for data-related jobs adheres more closely to the principle of least privilege, reducing the risk of accidental or malicious modifications to critical account settings.<br>- <strong>Operational efficiency:</strong> The Sysadmin role is optimized for performing and managing data operations, potentially offering more efficient execution of data-related jobs compared to using an account-wide administrative role, which is not specifically tailored for such tasks.<br>- <strong>Best practices and compliance:</strong> Using the Sysadmin role for database and job management aligns with best practices for managing cloud and database environments. It helps organizations to structure their roles and responsibilities in a way that enhances operational efficiency and security posture.</li></ul><h3>Connection Profiles</h3><p>Before creating a job in Control-M that can execute the jobs in this workflow, we will need to <a href="https://documents.bmc.com/supportu/API/Monthly/en-US/Documentation/API_CodeRef_ConnectionProfiles.htm">create connection profiles</a>. A connection profile contains authorization credentials — such as the username, password, and other plug-in-specific parameters — and enables you to connect to the application server with only the connection profile name. Connection profiles can be created using the web interface and then retrieved in JSON format using Control-M’s Automation API. Included below is a sample of the connection profile for Azure Databricks in JSON format. If you create the connection profile directly in JSON before running the job, it should be deployed using the Control-M Automation API CLI.</p><p><strong>Snowflake Connection Profile</strong></p><pre><br>{<br>  &quot;SF_JDBC_CONNECTION_PROFILE&quot;: {<br>    &quot;Type&quot;: &quot;ConnectionProfile:Database:JDBC&quot;,<br>    &quot;User&quot;: &quot;SMM&quot;,<br>    &quot;Driver&quot;: &quot;SNOWFLAKE_JDBC&quot;,<br>    &quot;Port&quot;: &quot;8443&quot;,<br>    &quot;DatabaseName&quot;: &quot;SNOWFLAKE_SAMPLE_DATA&quot;,<br>    &quot;Host&quot;: &quot;xyz.snowflakecomputing.com&quot;,<br>    &quot;Password&quot;: &quot;*****&quot;,<br>    &quot;Description&quot;: &quot;&quot;,<br>    &quot;Centralized&quot;: true<br>  }<br>}</pre><p>To connect to Snowflake we are using the Control-M Databases plug-in. Before setting it up you will need to download the JDBC driver for Snowflake which can be found at this link here. After downloading the JDBC driver you will need to place it on the Agent that will execute the jobs. For details, please see this link.</p><p><strong>MFT Connection Profile</strong></p><pre>{<br>&quot;AZSMB_BLOB&quot;: {<br>    &quot;Type&quot;: &quot;ConnectionProfile:FileTransfer:Azure:SharedKey&quot;,<br>    &quot;VerifyBytes&quot;: true,<br>    &quot;AzureAccountName&quot;: &quot;sambloblake&quot;,<br>    &quot;VerifyDestination&quot;: true,<br>    &quot;AzureStorageType&quot;: &quot;BLOB_STORAGE&quot;,<br>    &quot;AzureAccountAccessKey&quot;: &quot;*****&quot;,<br>    &quot;Description&quot;: &quot;&quot;,<br>    &quot;Centralized&quot;: true<br>  }<br>}</pre><p><strong>Kubernetes Connection Profile</strong></p><pre>{<br>&quot;MOL-K8S-CONNECTION-PROFILE&quot;: {<br>  &quot;Type&quot;: &quot;ConnectionProfile:Kubernetes&quot;,<br>  &quot;Service Token File&quot;: &quot;/var/run/secrets/kubernetes.io/serviceaccount/token&quot;,<br>  &quot;Namespace&quot;: &quot;default&quot;,<br>  &quot;Kubernetes Cluster URL&quot;: &quot;https://kubernetes.default.svc&quot;,<br>  &quot;Connection Timeout&quot;: &quot;50&quot;,<br>  &quot;Description&quot;: &quot;&quot;,<br>  &quot;Centralized&quot;: true<br>}<br>}</pre><p><strong>AWS Glue Connection Profile:</strong></p><pre>{<br>  &quot;MOLGLUECONNECTIONPROFILE&quot;: {<br>    &quot;Type&quot;: &quot;ConnectionProfile:AWS Glue&quot;,<br>    &quot;AWS Access key ID&quot;: &quot;&lt;Access Key&gt;&quot;,<br>    &quot;AWS Secret&quot;: &quot;*****&quot;,<br>    &quot;Authentication&quot;: &quot;SECRET&quot;,<br>    &quot;AWS Region&quot;: &quot;us-west-2&quot;,<br>    &quot;Glue url&quot;: &quot;glue.us-west-2.amazonaws.com&quot;,<br>    &quot;Connection Timeout&quot;: &quot;40&quot;,<br>    &quot;Description&quot;: &quot;&quot;,<br>    &quot;Centralized&quot;: true<br>  }<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a23907adc1af" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/orchestrating-a-multi-cloud-fraud-analytics-pipeline-with-control-m-a23907adc1af">Orchestrating a multi-cloud fraud analytics pipeline with Control-M</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introduction to LLMOps]]></title>
            <link>https://medium.com/bmc-digital-it/introduction-to-llmops-6a9a9b99e790?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/6a9a9b99e790</guid>
            <category><![CDATA[orchestration]]></category>
            <category><![CDATA[llmops]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[control-m]]></category>
            <dc:creator><![CDATA[Control-M Tech Blogs]]></dc:creator>
            <pubDate>Mon, 30 Jun 2025 14:43:09 GMT</pubDate>
            <atom:updated>2025-06-23T21:34:22.300Z</atom:updated>
            <content:encoded><![CDATA[<p>By <a href="https://www.linkedin.com/in/sumit-p-2127544/">Sumit Pal</a> and <a href="https://www.linkedin.com/in/basil-faruqui-b1a4b059/">Basil Faruqui</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nJmvpKu3TzE73cktwkCKNg.jpeg" /></figure><p>Though digital transformation has become a necessity for enterprises to survive, thrive and succeed, organizations routinely struggle with fragmented and rigid tools, data silos with automation and fragmented workflows that hinder scalability and efficiency.</p><p>Language models have unlocked possibilities of improving how business and technical users interact with existing business processes and leverage AI to orchestrate and communicate with each other through natural language.</p><p>This two-part blog series discusses the rapidly evolving landscape of LLMOps.</p><h3>What is LLMOps (Large Language Model Operations)</h3><p>LLMOps is the emerging practice of operational management of LLMs &amp; LLM-driven AI applications. It comprises of associated processes, tools, frameworks, libraries, infrastructure, orchestration and workflows as part of the lifecycle of AI-driven applications.</p><p>This is an emerging field akin to the DevOps/DataOps and MLOps for building and creating a robust deployment and automation process that leverages LLMs for AI applications. The primary focus is on the automation of end-to-end workflows to operationalize, deploy, monitor, optimize and maintain LLM-powered AI applications to ensure scalability, reliability and governance in production.</p><h3>Why is LLMOps needed</h3><p>Despite the false notion of LLMs possessing superpowers, LLMs don’t manage themselves. Organizations leveraging LLM-powered applications without LLMOps are running blind.</p><p>As enterprises adopt AI practices with home grown or 3rd party AI models, LLMOps brings in the formal discipline of building, deploying and maintaining AI applications in production. It does this by addressing the automation, operational and governance challenges in deploying AI applications to production. LLMOps ensures enterprise AI applications are secure, repeatable, reliable and trustworthy.</p><p>The goal of LLMOps is twofold:</p><ul><li>Automate the building, deployment and maintenance of AI applications to production</li><li>Improve end user experience</li></ul><p>This is achieved with automated machine or human feedback that continually evaluates the applications, ensuring compliance and safety with appropriate guardrails to minimize risk of bias, manage data privacy and security issues surrounding AI applications. To maintain and continually enhance efficiency, reliability, and scalability of the inference process you need an AI application at runtime.</p><p>LLMOps is a critical enabler to ensure quality and prevent adversarial attacks, malicious prompt injections and maintain high relevancy of results by detecting and recalibrating model and data drift. Leveraging LLMs is expensive and LLMOps helps with cost management by analyzing usage and identifying inefficiencies, by tracking token usage.</p><h3>When should organizations use LLMOps</h3><p>Now that the importance of LLMOps is understood the next question that arises is when to apply LLMOps and when not to.</p><p>Implementing AI-driven applications with LLMs runs into the following key challenges –which LLMOps can effectively overcome.</p><p>Managing data is a central tenet of building successful LLM-powered AI solutions. This involves identifying domain-specific/agnostic high-quality diverse data sources, preprocessing it for model training. Storing the metadata associated with these datasets for efficacy and relevance of LLM training, fine-tuning in intelligent automation frameworks.</p><p>LLM-powered AI solutions when deployed to production introduces several challenges which require model monitoring with LLMOps. Continuous model monitoring is essential to detect data and model drift to ensure model reliability and accuracy.</p><p>For organizations developing in-house LLMs or doing fine-tuning of existing LLM models, managing the size and complexity of LLM models requires robust infrastructure with demanding SLAs across latency, concurrency, scalability, High Availability (HA), and failover. LLMOps is a no-brainer in this case.</p><p>Most organizations will not develop in-house LLMs but rather leverage LLM APIs or implement AI solutions for proprietary data using Retrieval Augmented Generation (RAG) pattern to develop in-house AI applications. In the latter cases, guardrails around security, compliance, privacy of sensitive data and precautions against adversarial attacks, automated validation checks, and human-in-the-loop tests are the tasks that need to be orchestrated and coordinated in a reliable workflow with LLMOps processes, frameworks and tools.</p><p>As LLMs get increasingly integrated in the enterprises, that involves complex decision-making tasks, LLMOps ensures capabilities like anomaly detection, detecting deviations from expected behavior, error detection and error handling and appropriate altering mechanisms are in place to course correct the system behavior.</p><p>LLMOps is a critical part of optimizing costs incurred with using external AI models with cost effective resource management with serverless architectures, auto-scaling and maintaining SLAs.</p><p>Automation in complex systems requires LLMs to work in conjunction with other AI powered systems and models as well as agents. LLMOps orchestrates these multi-modal systems, ensuring they coordinate and work synergistically, and that effective and efficient agents communicate with shared context.</p><p>RAG-based AI solutions require integration between LLMs and external data and knowledge sources. The complexity of managing LLM workflows with data retrieval, data ranking and data augmentation is handled by LLMOps in making these cross-system integrations reliable, minimizing latency and coordinating the workflows with requisite SLAs.</p><p>LLMOps plays a pivotal role in the operational success of Agentic AI by addressing challenges of task execution and managing how agents interact with each other and external systems in a reliable, secure, and efficient manner.</p><p>LLMOps ensures that AI systems are deployed efficiently, effectively, with robust monitoring, security, and scalability. LLMOps provides the necessary framework to continuously improve the performance of LLM applications as they interact with dynamic environments, external knowledge bases, and autonomous task execution systems.</p><h3>DataOps, MLOps, LLMOps</h3><p>Data Operations (DataOps) is to data engineering what Machine Learning Operations (MLOps) is to ML Engineering and LLMOps is to AI Engineering. DataOps and MLOps are pre-requisites for LLMOPs. LLMOps takes the foundational principles of traditional MLOps and adapts them to the unique context of managing and deploying large-scale language models and applications.</p><p>MLOps is complex with its variety of tasks that are needed to integrate with multiple components of an ML engineering pipeline. LLMOps is like MLOps but with higher levels of complexity as it involves cost effectively provisioning and managing infrastructure — expensive resources like GPUs and TPUs and managing large models that span across machines and require extensive computational resources for training and inference.</p><p>LLM-based applications also requires extensive data caching (answers, prompts etc.) as well as integrating with external systems for incorporating RAG patterns. LLMOPs orchestrates and coordinates the different tasks and integrates with AI tools and frameworks in the ecosystem, ensures governance, data privacy, and mitigates hallucinations.</p><p>LLMOps helps with managing, curation, augmentation of huge volumes of heterogeneous training data to enhance the versatility across contexts multilingually. This includes multi-modal data sets that involve mainly unstructured data in the form of text, image, audio, video etc.</p><p>Determining the efficacy and trustability of LLMs in language-related tasks is an intricate process that’s distinct from traditional MLOps evaluation methods. These metrics try to quantify language output quality for coherence, fluency, consistency, conformity and language generation alignment and contextual appropriateness. This is an integral part of LLMOps, something not imperative with MLOps.</p><p>The core principles of MLOps are to bring ML applications and algorithms to production reliably. This still applies to LLMOPs but the complexities around LLMs requires LLMOps to go beyond by incorporating tasks like prompt engineering, prompt management, data preparation for fine-tuning, evaluation focused on the specific task, and continuous monitoring for output quality and integrating with RAG platforms and frameworks.</p><h3>LLMOps Market and Trends</h3><p>As Generative AI adoption accelerates and permeates into the enterprise, organizations need to adopt LLMOps to address unique challenges of LLMs. The ability to handle complex tasks like RAG, fine-tuning, data and workflow orchestration, governance, and cost efficiency in large-scale AI deployments is increasingly becoming critical for organizations adopting AI.</p><p>AI is forcing organizations to rethink their data, ML and AI infrastructure to optimize performance, reduce costs, improve latency and increase high availability along with addressing security and governance issues associated with AI.</p><p>LLMOps is a fast-moving field, and the tools and frameworks are continuously improving and adapting to the new developments in the GenAI and AI space. Existing LLMOps frameworks are keeping up with integration of new APIs, integrating with new upcoming models and integrating new protocols to interface with LLMs.</p><p>LLMOps is not about deploying a single model or integrating with AI APIs or chaining together agents. It increasingly requires building autonomous self-healing workflows, especially with the rise of agentic systems enabling AI-driven automation to be more effective and seamless. LLMOps tools are integrating with multiple specialized agentic frameworks optimized for different tasks.</p><p>LLMOps is evolving to integrate observability in the stack which includes model monitoring to detect model and data drift, performance optimization to handle latency spikes and auto configuring infrastructure based on usage, availability and SLAs. LLMOps tools and frameworks are adopting plug-and-play and modular development techniques to manage the ever-growing list of integrations.</p><p>As LLMOps matures, the concept of LLMOps marketplace for LLMOps components and AI models and operators will probably take shape, lower barriers to adoption, encourage standardization, and foster innovation across industries.</p><h3>Role of workflow &amp; orchestration in DataOps, MLOps, LLMOps</h3><p>Orchestration and workflow with LLMOps can be looked at 2 different lens — at a macro level and at a micro (granular level).</p><p>At a macro level, LLMOps facilitates the seamless integration of LLMs, AI frameworks, tools, agents and automation tool and workflows across data centers. The overarching goal is to ensure LLMs and other modular AI components be effectively utilized across diverse enterprise use cases and business functions across geographical regions.</p><p>This includes:</p><ul><li>Prompt Management — prompt versioning and keeping all the metadata associated with prompts for repeatability</li><li>Input, prompt and out processing</li><li>Data and prompt versioning</li><li>Handling of model-specific parameters and configurations</li><li>Chaining of multiple LLM invocations</li><li>Integrating external tools or APIs</li></ul><p>At a micro level, orchestration and workflow means building LLMs with data and ML pipelines with fine-grained control, coordination, orchestration across each of the pieces in the LLM development process. This encapsulates the granular details of how data flows into, through and out of language models within a single task or a small set of closely related tasks.</p><p>Consider a large insurance company automating its claims processing and reconciliation workflow leveraging LLMs as a part of the workflow and integration with other business processes. It consists of the following steps at a high level.</p><ol><li>Data Ingestion Layer: Customer data, claims forms, call transcripts, and documents are ingested from various sources like CRM systems, scanned PDFs, emails, and contact center logs.</li><li>Data Pipeline: The ingestion pipeline cleans, deduplicates, and enriches the data before it’s stored in a data lake or forwarded for downstream processing.</li><li>LLM Layer:<br>- LLM processes text from claims and call transcripts, extract relevant entities (e.g., policy number, date of loss, incident type).<br>- LLMs generates summaries and answers to queries about specific claims using context-aware prompts<br>- Prompt templates and responses are versioned and tracked for auditing and compliance.</li><li>Integration with Enterprise Systems:<br>- The extracted insights and responses are orchestrated into SAP for financial reconciliation, Oracle ERP for workflow updates, and Core Banking Systems for payment processing.<br>- In case of discrepancies, the LLM suggests possible resolutions by comparing current inputs with historical claim data.</li><li>Automation and Decisioning:<br>- If the claim meets certain thresholds, the system automatically routes it for approval.<br>- In complex cases, an LLM agent drafts a recommended response for a human adjuster to review, reducing time-to-resolution.</li></ol><p>All actions and tasks need to be woven into a workflow that involves DataOps for data pipelines, MLOps for ML and NLP tasks and LLMOps for LLM specific tasks. Enterprise workflow and BPM tools and frameworks like <a href="https://www.bmc.com/it-solutions/control-m.html">Control-M</a>, seamlessly coordinate and manage interaction, deployment, and integration of various pieces of the end-to-end chain of tasks and operations. This offers a multitude of benefits from scalability, efficiency, reliability, flexibility and consistency of enterprise-level workflows.</p><h3>Conclusion</h3><p>Building AI-driven applications powered by LLMs without a well-defined Ops model is relatively easy but quickly becomes challenging in production opening a Pandora’s box of models, challenges with data, and governance. <br>LLMOps is key to the building blocks of AI applications, that involves developing a structured framework which securely stores and processes data at scale and can safely extract data, and ensure language models do not misinterpret information, expose confidential data or generate potentially harmful answers.</p><p>LLMOps streamlines development, reduces risks, protects data, and optimizes costs, ultimately enhancing the quality of LLM apps. As AI usage grows, embracing LLMOps is key for companies to build great user experiences, maintain a competitive edge, and innovate efficiently.<br>Providing the infrastructure, tooling, and processes necessary to deploy, monitor, and continuously improve LLMs, LLMOps ensures that these models can be operationalized effectively in real-world automation scenarios.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6a9a9b99e790" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/introduction-to-llmops-6a9a9b99e790">Introduction to LLMOps</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[3 Steps to Digital Onboarding That Empowers Your Workforce]]></title>
            <link>https://medium.com/bmc-digital-it/3-steps-to-digital-onboarding-that-empowers-your-workforce-7b0e56b711bb?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/7b0e56b711bb</guid>
            <category><![CDATA[digital-transformation]]></category>
            <category><![CDATA[information-technology]]></category>
            <category><![CDATA[human-resources]]></category>
            <category><![CDATA[software]]></category>
            <category><![CDATA[tech]]></category>
            <dc:creator><![CDATA[BMC Software]]></dc:creator>
            <pubDate>Fri, 11 Nov 2016 19:47:46 GMT</pubDate>
            <atom:updated>2016-11-11T19:47:46.128Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*x_aAf86Ea7g4MqqR." /></figure><p>When it comes to attracting top-notch millennial talent, innovative onboarding tools aren’t simply a luxury, they’re a necessity. In fact, a 2015 <a href="http://www.upskillamerica.org/resources/talent-sustainability-report/">HR Policy Foundation (HRPF) study of millennials in the workforce</a> found 54 percent of companies have revised their onboarding process to be more appealing to millennials.</p><p>HRPF researchers say that slow hiring processes and lackluster training programs can cost companies the very talent they’re working so hard to attract. Workers who have grown up in a digital world expect the hiring process to reflect what’s become a standard way of life for them. Fortunately, it’s a demand worth meeting because a digital onboarding experience also frees up HR professionals to be more productive and time-efficient.</p><p>A strong digitized onboarding process sets the tone right from the start that you’re a forward-thinking company with a trained eye on what millennials look for in an employer. There are several new hire touchpoints that are ripe for digitized onboarding. Here are three processes you can implement today.</p><h3>Develop electronic forms for an improved hiring experience</h3><p>There’s no getting around it, forms and contracts are a part of virtually every new hire workflow. Payroll and tax forms, NDAs, employee contracts and policy manuals are just the beginning of the mountain of physical paperwork associated with onboarding new talent.</p><p>It’s a headache for new workers and an expensive compliance, storage and management issue for HR departments. As a result, many companies are turning to digital options, like <a href="http://www.bmc.com/it-solutions/hr-case-management.html">BMC HR Case Management</a>. The system automates routine HR processes with a digital workspace that includes over 300 best practice templates and more than 60 eForms that new hires can complete and return in the mobile or desktop environment of their choice. HR Case Management also makes quick work of converting and importing paper forms into the digital environment for a seamless transition for an online onboarding experience.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*k2lAl_VN-UL4KM6x." /></figure><h3>Digitize new hire portals for long-term success</h3><p>“Did you know 80 percent of millennials sleep with their phone within reach at night? Give them what they want. Ditch the chalkboard and move your onboarding information online,” <a href="https://learncore.com/understanding-the-millennial-mindset/">Leanrcore says</a> of today’s hiring process.</p><p>By digitizing the onboarding process, workers become immediately acclimated to HR processes that will follow them throughout the length of their employment with your company. From expense reimbursements and internal transfer requests to exit interview questionnaires, HR Case Management empowers employees to help themselves find the answers they need quickly, reducing the overall workload for HR staff and service center agents.</p><h3>Create an interactive workspace to engage employees</h3><p>Once you’ve located top-notch millennial talent, training is the key to keeping them. “To keep Deloitte’s youngest employees satisfied, chief talent officer Mike Preston says he has focused on creating a ‘development culture,” <a href="http://fortune.com/2016/03/04/attracting-millennial-talent/">Fortune explains</a>. In order to foster employee loyalty and retention, “Deloitte doubled down on sending employees to training programs, and managers are expected to have frequent check-in conversations.”</p><p>Take Deloitte’s idea to the next level by creating an interactive workspace for each employee. Empower them to navigate independently through the system to easily find relevant training information and content. HR Case Management’s data security tools not only protect user privacy, they also make sure employees can only see information and content related to their role in the company. A built-in drag-and-drop process designer lets staff effortlessly create new content or processes in just a few clicks, keeping HR teams agile and independent.</p><p>Today’s millennials want contemporary digital services in the workplace. Exceed their expectations with technology that makes people as productive as possible, as quickly as possible, and make sure they enjoy the experience along the way.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7b0e56b711bb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/3-steps-to-digital-onboarding-that-empowers-your-workforce-7b0e56b711bb">3 Steps to Digital Onboarding That Empowers Your Workforce</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Executing an Effective IT Governance Strategy]]></title>
            <link>https://medium.com/bmc-digital-it/executing-an-effective-it-governance-strategy-cb146a023abf?source=rss----c83eeec4e799---4</link>
            <guid isPermaLink="false">https://medium.com/p/cb146a023abf</guid>
            <category><![CDATA[digital-transformation]]></category>
            <category><![CDATA[information-technology]]></category>
            <category><![CDATA[big-data]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[information-security]]></category>
            <dc:creator><![CDATA[BMC Software]]></dc:creator>
            <pubDate>Fri, 11 Nov 2016 19:31:25 GMT</pubDate>
            <atom:updated>2016-11-11T19:32:06.382Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*8ta7FMfBLYi3Sw18." /></figure><p>The digital revolution is well underway. In fact, a range of e-services — from online voting to taxation to e-banking and even an Internet-based Governance Academy — are being supported by countries like Estonia, the <a href="https://www.kyivpost.com/technology/estonia-ditches-paper-model-e-governance-services-infographic.html">Kyiv Post</a> notes. Estonia’s results speak for themselves: The country now saves 2 percent of its GDP each year through paperless initiatives. But this kind of shift doesn’t happen in a vacuum. Detailed, descriptive IT governance is needed to make the move from traditional processes to digital alternatives, and strategy is the key to long-term IT success.</p><h3>Grounding Governance</h3><p>What exactly is IT governance? Research firm <a href="http://www.gartner.com/it-glossary/it-governance/">Gartner</a> defines it as “the processes that ensure the effective and efficient use of IT in enabling an organization to achieve its goals.” Put simply, governance is the planning behind the IT procedures companies utilize every single day. Ideally, strategies ensure that IT aims to both align with corporate goals and deliver measurable returns.</p><h3>Strategy Sessions</h3><p>How do you build an effective IT governance plan that is realistic, transparent and supports ongoing improvement? Start by identifying key data:</p><ul><li>How are current IT processes — InfoSec, cloud initiatives and day-to-day operations such as CRM or ERP deployments — performing over time?</li><li>Is there room for improvement?</li></ul><p>Next, select a team of key decision makers and assign progressive responsibility. Typically, CTOs or CIOs top the list here, but it’s worth bringing at least one other executive and strong IT managers on board to ensure you get a range of opinions.</p><p>With your team in place, determine areas in need of immediate improvement and identify key metrics of success. Consider data security. If your company is stuck in a “reactive” threat model, it may be worth designing an IT governance strategy to address and mitigate this risk. Metrics here could include the total number of successful breaches, malware and DDoS efforts stopped or detected before they cause any damage and any information obtained about new threat vectors from quarantined attacks. And as noted by an <a href="https://www.isaca.org/Certification/CGEIT-Certified-in-the-Governance-of-Enterprise-IT/Prepare-for-the-Exam/Study-Materials/Documents/Developing-a-Successful-Governance-Strategy.pdf">ISACA whitepaper</a>, it’s also critical to design a realistic IT governance strategy, one “consistent with your organization’s management style and the way your organization deals with risk management and delivery of IT value.” In other words, going too far off the beaten path makes an IT strategy unsustainable since users will push back and governance efforts won’t sync with everyday processes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*92a1f3rg82efrLTy." /></figure><h3>Prioritizing Performance</h3><p>With a basic strategy outline in place, your team needs to identify key areas of improvement and then adopt specific technology solutions to maximize performance. Consider the emerging problem of server configuration and management; many companies now run multiple server environments across local stacks, public clouds and co-location databases, making provision and troubleshooting a huge time investment. Specific IT governance here might include the adoption of <a href="http://www.bmcsoftware.ca/it-solutions/bladelogic-server-automation.html">BMC’s BladeLogic Server Automation tool</a>, which streamlines this process and lets IT pros embrace other revenue-positive projects. For example, BladeLogic lets IT pros configure automatic resource provisioning, patching and reporting in addition to role-based access controls to help ensure IT compliance.</p><p>Shadow IT is another common problem for governance efforts. The threat of Shadow IT emerges when tech-savvy employees feel IT rules regarding application, service or social media access are needlessly restrictive. These employees end up using cloud computing deployments and mobile devices to circumvent IT controls if the application they prefer isn’t available or approved. By leveraging tools such as <a href="http://www.bmcsoftware.ca/it-solutions/myit-service-broker.html">MyIT Service Broker</a>, it’s possible to empower employees without encouraging the growth of Shadow IT. Staff get access to a huge catalog of useful and responsive apps, while IT admins gain the ability to manage, deliver and track software and services.</p><p>Bottom line? Better strategy means better IT governance. By taking the time to identify areas of concern, build the right team and ensure new initiatives align with existing corporate priorities, it’s possible to draft governance policy which clearly communicates expectations, embraces new technology and ultimately drives ROI.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cb146a023abf" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bmc-digital-it/executing-an-effective-it-governance-strategy-cb146a023abf">Executing an Effective IT Governance Strategy</a> was originally published in <a href="https://medium.com/bmc-digital-it">BMC Innovation</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>