Skip to content

Commit

Permalink
Merge branch 'awslabs:main' into feat/sagemaker-model-cicd
Browse files Browse the repository at this point in the history
  • Loading branch information
nagyen authored Jul 4, 2024
2 parents b750569 + 7bb3037 commit 11fc50a
Show file tree
Hide file tree
Showing 48 changed files with 107 additions and 104 deletions.
6 changes: 6 additions & 0 deletions .github/ISSUE_TEMPLATE/missing_integ_tests_issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
name: Missing Integration Tests
title: "[CHORE] Module {{env.MODULE_PATH }} missing integration tests"
labels: workflows, backlog
assignees: ''
---
60 changes: 60 additions & 0 deletions .github/workflows/check-integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Check Modules for Integration Tests

on:
workflow_dispatch:
schedule:
- cron: "0 */3 * * *"

jobs:
get-modules:
name: Get Modules
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.get-modules.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get modules
id: get-modules
run: |
MODULES=()
MODULES_WITHOUT_INTEG=()
for d in modules/*/* ; do
MODULES+=("$d")
done
for m in "${MODULES[@]}" ; do
if [ ! -d "${m}"/integ/ ]; then
echo "No Integration tests for ${m}"
MODULES_WITHOUT_INTEG+=("$m")
fi
done
echo "${MODULES_WITHOUT_INTEG[@]}"
# Create our json structure [{"module_path": "..."}]
MODULES_JSON=$(echo "${MODULES_WITHOUT_INTEG[@]}" | jq -R -s 'split(" ")' | jq '[ .[] | select(length > 0) ]' | jq 'map({"module_path": .})')
# Export the modules as json to the outputs
echo 'matrix<<EOF' >> $GITHUB_OUTPUT
echo $MODULES_JSON >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
create-issues:
name: Create issue for ${{ matrix.modules.module_path }}
needs: get-modules
permissions:
contents: read
issues: write
strategy:
fail-fast: false
matrix:
modules: ${{ fromJson(needs.get-modules.outputs.matrix) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: JasonEtco/create-an-issue@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MODULE_PATH: ${{ matrix.modules.module_path }}
with:
filename: .github/ISSUE_TEMPLATE/missing_integ_tests_issue.md
update_existing: false
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- fix inputs for `bedrock-finetuning` module not working
- add `retention-type` argument for the bucket in the `bedrock-finetuning` module
- fix broken dependencies for `examples/airflow-dags`
- use `add_dependency` to avoid deprecation warnings from CDK.
- use `add_dependency` to avoid deprecation warnings from CDK
- various typo fixes
- various clean-ups to the SageMaker Service Catalog templates
- fix opensearch removal policy

## v1.2.0

Expand Down
4 changes: 2 additions & 2 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export PRIMARY_ACCOUNT=XXXXXXXXXXXX
export ADMIN_ROLE_ARN=arn:aws:iam::XXXXXXXXXXXX:role/XXXXX
```

5. Bbootstrap the CDK environment (one time per region) with CDK V2. Asuming you are deploying in `us-east-1`:
5. Bootstrap the CDK environment (one time per region) with CDK V2. Assuming you are deploying in `us-east-1`:
```
cdk bootstrap aws://${PRIMARY_ACCOUNT}/us-east-1
```
Expand All @@ -44,7 +44,7 @@ seedfarmer bootstrap toolchain --project aiops --trusted-principal ${ADMIN_ROLE_

## Deployment

Pick the manifest to deploy. Manifests are located in `mainfests/` directory. For example, to deploy SageMaker mlops manifests, run:
Pick the manifest to deploy. Manifests are located in `manifests/` directory. For example, to deploy SageMaker mlops manifests, run:

!Note: if you are deploying into a region different from `us-east-1`, change the `regionMappings` in `deployment.yaml`.
```
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AIOps Modules

AIOps modules is a collection of resuable Infrastructure as Code (IAC) modules that works with [SeedFarmer CLI](https://github.com/awslabs/seed-farmer). Please see the [DOCS](https://seed-farmer.readthedocs.io/en/latest/) for all things seed-farmer.
AIOps modules is a collection of reusable Infrastructure as Code (IAC) modules that works with [SeedFarmer CLI](https://github.com/awslabs/seed-farmer). Please see the [DOCS](https://seed-farmer.readthedocs.io/en/latest/) for all things seed-farmer.

The modules in this repository are decoupled from each other and can be aggregated together using GitOps (manifest file) principles provided by `seedfarmer` and achieve the desired use cases. It removes the undifferentiated heavy lifting for an end user by providing hardended modules and enables them to focus on building business on top of them.

Expand Down
2 changes: 1 addition & 1 deletion manifests/fmops-qna-rag/storage-modules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ parameters:
- name: encryption-type
value: SSE
- name: retention-type
value: RETAIN
value: DESTROY
- name: vpc-id
valueFrom:
moduleMetadata:
Expand Down
4 changes: 2 additions & 2 deletions modules/eks/ray-on-eks/deployspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ deploy:
eksctl get iamidentitymapping --cluster ${SEEDFARMER_PARAMETER_EKS_CLUSTER_NAME} --arn ${EKS_SERVICE_ACCOUNT_ROLE} \
&& echo "IAM Identity Mapping already found" \
|| eksctl create iamidentitymapping --cluster ${SEEDFARMER_PARAMETER_EKS_CLUSTER_NAME} --arn ${EKS_SERVICE_ACCOUNT_ROLE} --username ${SEEDFARMER_MODULE_NAME}
# Un-Assume the EKS_CLUSTER_ADMIN_ROLE or the rest of the deploy will faile
# Un-Assume the EKS_CLUSTER_ADMIN_ROLE or the rest of the deploy will fail
- unset AWS_ACCESS_KEY_ID && unset AWS_SECRET_ACCESS_KEY && unset AWS_SESSION_TOKEN
destroy:
phases:
Expand All @@ -32,6 +32,6 @@ destroy:
eksctl get iamidentitymapping --cluster ${SEEDFARMER_PARAMETER_EKS_CLUSTER_NAME} --arn ${EKS_SERVICE_ACCOUNT_ROLE} \
&& eksctl delete iamidentitymapping --cluster ${SEEDFARMER_PARAMETER_EKS_CLUSTER_NAME} --arn ${EKS_SERVICE_ACCOUNT_ROLE} \
|| echo "IAM Identity Mapping not found"
# Un-Assume the EKS_CLUSTER_ADMIN_ROLE or the rest of the deploy will faile
# Un-Assume the EKS_CLUSTER_ADMIN_ROLE or the rest of the deploy will fail
- unset AWS_ACCESS_KEY_ID && unset AWS_SECRET_ACCESS_KEY && unset AWS_SESSION_TOKEN
- cdk destroy --force --all --app "python app.py"
2 changes: 1 addition & 1 deletion modules/examples/airflow-dags/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This module demonstrates:

## Inputs/Outputs

### Input Paramenters
### Input Parameters

#### Required

Expand Down
2 changes: 1 addition & 1 deletion modules/examples/airflow-dags/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def __init__(
),
NagPackSuppression(
id="AwsSolutions-IAM5",
reason="Resource access restriced to MLOPS resources.",
reason="Resource access restricted to MLOPS resources.",
),
NagPackSuppression(
id="AwsSolutions-IAM4",
Expand Down
4 changes: 2 additions & 2 deletions modules/examples/event-bus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This module creates an Amazon EventBridge Bus for cross-account events.

## Inputs/Outputs

### Input Paramenters
### Input Parameters

#### Required

Expand Down Expand Up @@ -48,4 +48,4 @@ parameters:
"EventBusArn": "arn:aws:events:xx-xxxx-x:xxxxxxxxxx:event-bus/mlops-bus",
"EventBusName": "mlops-bus",
}
```
```
2 changes: 1 addition & 1 deletion modules/fmops/bedrock-finetuning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This module presents how you can setup automated model finetuning in Amazon Bedr

## Description

The module creates a finetuning job for Amazon Bedrock model of choice (you provide the model's name in input, note that not all models on Amazon Bedrock can be finetuned currently). Finetuning is triggerred by droping new file into created S3 Bucket. This triggers step function execution that using Lambda invokes the finetuning job and provides all the necessary parameters. You can expand this solution by adding more steps to the step function or by adding other modules.
The module creates a finetuning job for Amazon Bedrock model of choice (you provide the model's name in input, note that not all models on Amazon Bedrock can be finetuned currently). Finetuning is triggered by dropping new file into created S3 Bucket. This triggers step function execution that using Lambda invokes the finetuning job and provides all the necessary parameters. You can expand this solution by adding more steps to the step function or by adding other modules.

## Architecture

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ def lambda_handler(event, context):
return {
"statusCode": 200,
"body": json.dumps(
f"Model finetuning started succesfully, job name: {job_name}"
f"Model finetuning started successfully, job name: {job_name}"
),
}
2 changes: 1 addition & 1 deletion modules/fmops/qna-rag/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Question and Answering using RAG Architecture
#### Required

- `cognito-pool-id` - ID of the cognito user pool, used to secure GraphQl API
- `os-domain-endpoint` - Open Search doamin url used as knowledge base
- `os-domain-endpoint` - Open Search domain url used as knowledge base
- `os-security-group-id` - Security group of open search cluster
- `vpc-id` - VPC id

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class SagemakerHuggingFaceEndpointStack extends cdk.Stack {
[
{
id: "AwsSolutions-IAM5",
reason: "Resource access restriced to S3 buckets (with a prefix) and ECR images",
reason: "Resource access restricted to S3 buckets (with a prefix) and ECR images",
},
],
true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class SagemakerJumpStartFmEndpointStack extends cdk.Stack {
cdk_nag.NagSuppressions.addResourceSuppressions(this.role, [
{
id: "AwsSolutions-IAM5",
reason: "Resource access restriced to S3 buckets (with a prefix) and ECR images",
reason: "Resource access restricted to S3 buckets (with a prefix) and ECR images",
},
]);
}
Expand Down
2 changes: 1 addition & 1 deletion modules/sagemaker/sagemaker-custom-kernel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This module builds custom kernel for SageMaker studio from a Dockerfile.

## Inputs/Outputs

### Input Paramenters
### Input Parameters

#### Required

Expand Down
2 changes: 1 addition & 1 deletion modules/sagemaker/sagemaker-model-package-group/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This module creates a SageMaker Model Package Group to register and version Sage

## Inputs/Outputs

### Input Paramenters
### Input Parameters

#### Required

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(
model_package_group_name
The Model Package Group name.
retain_on_delete, optional
Wether or not to retain resources on delete. Defaults True.
Whether to retain resources on delete. Defaults True.
target_event_bus_arn, optional
The event bus arn in to send events model package group state change events to.
It can be a bus located in another account. Defaults None.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A Seedfarmer module to deploy a Pipeline to promote SageMaker Model Packages in

## Inputs/Outputs

### Input Paramenters
### Input Parameters

#### Required

Expand All @@ -24,7 +24,7 @@ A Seedfarmer module to deploy a Pipeline to promote SageMaker Model Packages in
- `sagemaker_project_id`: The SageMaker project id to associate with the model package group.
- `sagemaker_project_name`: The SageMaker project name to associate with the model package group.
- `kms_key_arn`: The KMS Key ARN to encrypt model artifacts.
- `retain_on_delete`: Wether or not to retain model package resources on delete. Defaults True. This applies only to the sagemaker model package resources and not to the resources in this stack.
- `retain_on_delete`: Whether to retain model package resources on delete. Defaults True. This applies only to the sagemaker model package resources and not to the resources in this stack.

### Sample manifest declaration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(
bucket_name
The S3 bucket name to store model artifacts.
retain_on_delete, optional
Wether or not to retain resources on delete. Defaults True.
Whether to retain resources on delete. Defaults True.
model_package_group_name, optional
The SageMaker model package group name to register the model package. Defaults None. If None
it will use the model package group name that is in the model metadata.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __init__(
kms_key_arn
The KMS Key ARN to encrypt model artifacts.
retain_on_delete
Wether or not to retain model package resources on delete. Defaults True. This applies only
Whether to retain model package resources on delete. Defaults True. This applies only
to the sagemaker model package resources and not to the resources in this stack.
"""
super().__init__(scope, construct_id, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion modules/sagemaker/sagemaker-notebook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This module creates a SageMaker Notebook instance.

## Inputs/Outputs

### Input Paramenters
### Input Parameters

#### Required

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def delete_app(app):
AppName=app["AppName"],
)
else:
print("App already delted")
print("App already deleted")
except Exception as e:
print(f"\tError deleting app: {e}")

Expand Down
2 changes: 1 addition & 1 deletion modules/sagemaker/sagemaker-studio/scripts/delete_efs.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def process(efs_id: str, domain_id: str) -> None:
print(f"Deleting mount target {mount_target_id}")
delete_mount_target(mount_target_id)

print("Sleeping to allow mount targts to delete")
print("Sleeping to allow mount targets to delete")
time.sleep(35)
print(f"Deleting FileSystem {efs_id}")
delete_file_system(efs_id=efs_id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The module contains ogranizational SageMaker Project Templates vended as Service

The template contains an example SageMaker Pipeline to train a model on Abalone dataset using XGBoost, and perform model evaluation.

![Abalone wtih XGBoost](docs/_static/abalone-xgboost-template.png "Abalone with XGBoost Template Architecture")
![Abalone with XGBoost](docs/_static/abalone-xgboost-template.png "Abalone with XGBoost Template Architecture")

The template is based on basic multi-account template from [AWS Enterprise MLOps Framework](https://github.com/aws-samples/aws-enterprise-mlops-framework/blob/main/mlops-multi-account-cdk/mlops-sm-project-template/README.md#sagemaker-project-stack).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def get_pipeline(
outputs=[
ProcessingOutput(output_name="output_data", source="/opt/ml/processing/output_data"),
],
code="source_scripts/preprocessing/prepare_abalone_data/main.py",
code="source_scripts/preprocessing.py",
job_arguments=[
"--input-data",
input_data,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(
) -> None:
super().__init__(scope, construct_id)

# Define required parmeters
# Define required parameters
project_name = aws_cdk.CfnParameter(
self,
"SageMakerProjectName",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# SageMaker Pipelines

This folder contains SageMaker Pipeline definitions and helper scripts to either simply "get" a SageMaker Pipeline definition (JSON dictionnary) with `get_pipeline_definition.py`, or "run" a SageMaker Pipeline from a SageMaker pipeline definition with `run_pipeline.py`.
This folder contains SageMaker Pipeline definitions and helper scripts to either simply "get" a SageMaker Pipeline definition (JSON dictionary) with `get_pipeline_definition.py`, or "run" a SageMaker Pipeline from a SageMaker pipeline definition with `run_pipeline.py`.

Those files are generic and can be reused to call any SageMaker Pipeline.

Each SageMaker Pipeline definition should be be treated as a module inside its own folder, for example here the
Each SageMaker Pipeline definition should be treated as a module inside its own folder, for example here the
"training" pipeline, contained inside `training/`.
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def __init__(
"echo $SCAN_RESULT",
"echo $FAIL_BUILD",
"""if [[ "$FAIL_BUILD" = "true" && "$SCAN_RESULT" = "FAILED" ]]; then printf "\n\n
Failiing pipeline as possible insecure configurations were detected
Failing pipeline as possible insecure configurations were detected
\n\n" && exit 1; fi""",
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

def invoke_endpoint(endpoint_name):
"""
Add custom logic here to invoke the endpoint and validate reponse
Add custom logic here to invoke the endpoint and validate response
"""
return {"endpoint_name": endpoint_name, "success": True}

Expand All @@ -48,7 +48,7 @@ def test_endpoint(endpoint_name):
logger.error(error_message)
raise Exception(error_message)

# Output if endpoint has data capture enbaled
# Output if endpoint has data capture enabled
endpoint_config_name = response["EndpointConfigName"]
response = sm_client.describe_endpoint_config(EndpointConfigName=endpoint_config_name)
if "DataCaptureConfig" in response and response["DataCaptureConfig"]["EnableCapture"]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ This folder contains all the SageMaker Pipelines of your project.

`buildspec.yml` defines how to run a pipeline after each commit to this repository.
`ml_pipelines/` contains the SageMaker pipelines definitions.
The expected output of the your main pipeline (here `training/pipeline.py`) is a model registered to SageMaker Model Registry.
The expected output of the main pipeline (from `training/pipeline.py`) is a model registered to SageMaker Model Registry.

`source_scripts/` contains the underlying scripts run by the steps of your SageMaker Pipelines. For example, if your SageMaker Pipeline runs a Processing Job as part of a Processing Step, the code being run inside the Processing Job should be defined in this folder.
A typical folder structure for `source_scripts/` can contain `helpers`, `preprocessing`, `training`, `postprocessing`, `evaluate`, depending on the nature of the steps run as part of the SageMaker Pipeline.
We provide here an example with the Abalone dataset, to train an XGBoost model (using), and exaluating the model on a test set before sending it for manual approval to SageMaker Model Registry inside the SageMaker ModelPackageGroup defined when creating the SageMaker Project.
We provide here an example with the Abalone dataset, to train an XGBoost model (using), and evaluating the model on a test set before sending it for manual approval to SageMaker Model Registry inside the SageMaker ModelPackageGroup defined when creating the SageMaker Project.
Additionally, if you use custom containers, the Dockerfile definitions should be found in that folder.

`tests/` contains the unittests for your `source_scripts/`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def get_pipeline(
ProcessingOutput(output_name="validation", source="/opt/ml/processing/validation"),
ProcessingOutput(output_name="test", source="/opt/ml/processing/test"),
],
code="source_scripts/preprocessing/prepare_abalone_data/main.py",
code="source_scripts/preprocessing.py",
job_arguments=["--input-data", input_data],
)

Expand Down Expand Up @@ -218,7 +218,7 @@ def get_pipeline(
outputs=[
ProcessingOutput(output_name="evaluation", source="/opt/ml/processing/evaluation"),
],
code="source_scripts/evaluate/evaluate_xgboost/main.py",
code="source_scripts/evaluate.py",
property_files=[evaluation_report],
)

Expand Down
Empty file.
Empty file.
Empty file.
Loading

0 comments on commit 11fc50a

Please sign in to comment.