Código para a pipeline de build
Definição do pipeline
resource "aws_codepipeline" "sm_ci_pipeline" {
name = "modelbuild-pipeline"
role_arn = aws_iam_role.tf_mlops_role.arn
tags = {
Environment = var.env
}
artifact_store {
location = aws_s3_bucket.artifacts_bucket.bucket
type = "S3"
}
stage {
name = "Source"
action {
category = "Source"
configuration = {
RepositoryName = var.build_repository_name
BranchName = var.repository_branch
PollForSourceChanges = true
}
input_artifacts = []
name = "Source"
output_artifacts = [
"SourceArtifact",
]
owner = "AWS"
provider = "CodeCommit"
run_order = 1
version = "1"
}
}
stage {
name = "Build"
action {
category = "Build"
configuration = {
"ProjectName" = "tf-mlops-modelbuild"
}
input_artifacts = [
"SourceArtifact",
]
name = "Build"
output_artifacts = [
"BuildArtifact",
]
owner = "AWS"
provider = "CodeBuild"
run_order = 1
version = "1"
}
}
}
Aqui definimos todos os aspectos de nossa pipeline, começando pela etapa de Source, definimos que a fonte vem de um repositório AWS CodeCommit, e colocamos seu nome, a branch a ser utilizada e o PollForSourceChanges
serve para a pipeline buscar por mudanças no código fonte e rodar a pipeline quando detectar mudanças.
Em seguida, temos a fase de build, que aqui colocamos o nome do projeto, porém vamos criar ela no próximo arquivo.
Por fim, essa etapa não possui fase de deploy.
Definição do CodeBuild
version: 0.2
phases:
install:
runtime-versions:
python: 3.8
commands:
- pip install --upgrade --force-reinstall . awscli
# Tire a linha abaixo quando for utilizar outros dados, esses são só para exemplo de pipeline.
- aws s3 cp s3://sagemaker-sample-files/datasets/tabular/synthetic/churn.txt s3://${ARTIFACT_BUCKET}/sagemaker/DEMO-xgboost-churn/data/RawData.csv
build:
commands:
- export PYTHONUNBUFFERED=TRUE
- export SAGEMAKER_PROJECT_NAME_ID="${SAGEMAKER_PROJECT_NAME}-${SAGEMAKER_PROJECT_ID}"
- |
run-pipeline --module-name pipelines.customer_churn.pipeline \
--role-arn ${SAGEMAKER_PIPELINE_ROLE_ARN} \
--tags "[{\"Key\":\"sagemaker:project-name\", \"Value\":\"${SAGEMAKER_PROJECT_NAME}\"}, {\"Key\":\"sagemaker:project-id\", \"Value\":\"${SAGEMAKER_PROJECT_ID}\"}]" \
--kwargs "{\"region\":\"${AWS_REGION}\",\"role\":\"${SAGEMAKER_PIPELINE_ROLE_ARN}\",\"default_bucket\":\"${ARTIFACT_BUCKET}\",\"pipeline_name\":\"${SAGEMAKER_PROJECT_NAME_ID}\",\"model_package_group_name\":\"${SAGEMAKER_PROJECT_NAME_ID}\",\"base_job_prefix\":\"${SAGEMAKER_PROJECT_NAME_ID}\"}"
- echo "Create/Update of the SageMaker Pipeline and execution completed."
Neste arquivo yml, definimos todas as etapas que o build deve executar, desde a instalação de dependências, até a execução da pipeline do sagemaker (opens in a new tab).
data "template_file" "buildspec" {
template = file("modelbuild_buildspec.yml")
vars = {
env = var.env
SAGEMAKER_PROJECT_NAME=var.project_name
SAGEMAKER_PROJECT_ID=var.project_id
ARTIFACT_BUCKET=var.artifacts_bucket_name
SAGEMAKER_PIPELINE_ROLE_ARN=aws_iam_role.tf_mlops_role.arn
AWS_REGION=var.region
SAGEMAKER_PROJECT_NAME_ID="${var.project_name}-${var.project_id}"
}
}
resource "aws_codebuild_project" "tf_mlops_modelbuild" {
badge_enabled = false
build_timeout = 60
name = "tf-mlops-modelbuild"
queued_timeout = 480
service_role = aws_iam_role.tf_mlops_role.arn
tags = {
Environment = var.env
}
artifacts {
encryption_disabled = false
name = "tf-mlops-modelbuild-${var.env}"
override_artifact_name = false
packaging = "NONE"
type = "CODEPIPELINE"
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "aws/codebuild/amazonlinux2-x86_64-standard:2.0"
image_pull_credentials_type = "CODEBUILD"
privileged_mode = false
type = "LINUX_CONTAINER"
environment_variable {
name = "environment"
type = "PLAINTEXT"
value = var.env
}
environment_variable {
name = "SAGEMAKER_PROJECT_NAME"
type = "PLAINTEXT"
value = var.project_name
}
environment_variable {
name = "SAGEMAKER_PROJECT_ID"
type = "PLAINTEXT"
value = var.project_id
}
environment_variable {
name = "ARTIFACT_BUCKET"
type = "PLAINTEXT"
value = var.artifacts_bucket_name
}
environment_variable {
name = "SAGEMAKER_PIPELINE_ROLE_ARN"
type = "PLAINTEXT"
value = aws_iam_role.tf_mlops_role.arn
}
environment_variable {
name = "AWS_REGION"
type = "PLAINTEXT"
value = var.region
}
}
logs_config {
cloudwatch_logs {
status = "ENABLED"
}
s3_logs {
encryption_disabled = false
status = "DISABLED"
}
}
source {
buildspec = data.template_file.buildspec.rendered
git_clone_depth = 0
insecure_ssl = false
report_build_status = false
type = "CODEPIPELINE"
}
}
Por fim, aqui definimos a etapa de build, onde no inicio do arquivo todas as variáveis do .yml são preenchidas por variáveis do terraform. Em seguida são configurados todos os aspectos do build, como o tipo de instância utilizada, a imagem utilizada na instância, todas as variáveis de ambiente utilizadas na pipeline, configura também os logs no cloudwatch e no desabilita eles no S3 e coloca o CODEPIPELINE como a fonte do código para o build.