Repositorio de infraestructura y servicios para Galaxy Morph, una plataforma distribuida para clasificacion de morfologia de galaxias.
Fase actual: foundation y preparacion de entorno.
Incluye:
- Estructura de carpetas para IaC, servicios y pruebas.
- Separacion de entornos
devyprod. - Base para observabilidad fuerte (CloudWatch y X-Ray).
No incluye aun:
- Provisionamiento Terraform funcional completo.
- Implementacion de logica de negocio en servicios.
- Pipeline de telescopios (fuera de alcance en esta fase).
- iac/: infraestructura como codigo con Terraform.
- services/: codigo de servicios (Lambdas, Spark/EMR, SageMaker, Kafka tools).
- docs/: documentacion de arquitectura, flujo y contribucion.
- scripts/: utilidades de desarrollo y release.
- tests/: pruebas de integracion y end-to-end.
- docs/galaxy_morph_architecture_knowledge.md: base de decisiones y contexto tecnico.
- docs/project_execution_flow.md: flujo completo del proyecto, etapas y servicios.
- docs/contribution_workflow.md: convenciones de contribucion, commits y PR.
- docs/implementation_roadmap.md: roadmap quincenal con owners, entregables y Definition of Done por etapa.
- Estrategia de ramas: GitFlow.
- Commits: Conventional Commits, atomicos y con scope.
- IaC y codigo de servicios se mantienen separados.
- Lambdas: TypeScript + Powertools for AWS Lambda.
- Spark: PySpark para procesamiento en EMR Serverless.
- Serving de modelo: Python para SageMaker.
- Region objetivo inicial:
us-east-2. - Entornos activos:
devyprod.
Ejecutar la Q2 del roadmap: bootstrap de estado remoto Terraform, bloqueo de estado y validacion en CI.
docker pull bridgecrew/checkov:3 docker run --rm -v ./iac:/tf --workdir /tf bridgecrew/checkov:3 --directory /tf -o junitxml --output-file-path results.xml
fase 1: en tfvars: enable_msk_connect_connector = false sagemaker_enable_endpoint = false
cd iac/environments/dev terraform apply -auto-approve
fase 2:
wget -q https://archive.apache.org/dist/kafka/3.5.1/kafka_2.13-3.5.1.tgz &&
tar -xzf kafka_2.13-3.5.1.tgz &&
wget -q
https://github.com/aws/aws-msk-iam-auth/releases/download/v2.3.0/aws-msk-iam-auth-2.3.0-all.jar
-P kafka_2.13-3.5.1/libs/
cat > client.properties << 'EOF' security.protocol=SASL_SSL sasl.mechanism=AWS_MSK_IAM sasl.jaas.config=software.amazon.msk.auth.iam.IAMLoginModule required; sasl.client.callback.handler.class=software.amazon.msk.auth.iam.IAMClientCallbackHandler EOF
export BS="boot-5mw8mtoy.c2.kafka-serverless.us-east-2.amazonaws.com:9098"
kafka_2.13-3.5.1/bin/kafka-topics.sh
--create --if-not-exists
--bootstrap-server $BS
--command-config client.properties
--replication-factor 2
--partitions 24
--topic galaxy.ingestion
kafka_2.13-3.5.1/bin/kafka-topics.sh
--create --if-not-exists
--bootstrap-server $BS
--command-config client.properties
--replication-factor 2
--partitions 24
--topic galaxy.results
kafka_2.13-3.5.1/bin/kafka-topics.sh
--list
--bootstrap-server $BS
--command-config client.properties
fase 3: en tfvars: enable_msk_connect_connector = true # ← cambiar sagemaker_enable_endpoint = false # ← sigue en false
terraform apply -auto-approve
fase 4:
cd services/ml/model_bundle && make upload
cd services/emr/jobs/streaming_classification && make upload
fase 5: en tfvars: enable_msk_connect_connector = true # ya estaba sagemaker_enable_endpoint = true # ← cambiar
cd iac/environments/dev terraform apply
aws sagemaker describe-endpoint
--endpoint-name galaxy-morph-dev-galaxy-classifier
--query 'EndpointStatus' --output text
--profile default --region us-east-2
fase 6: SAGEMAKER_ENDPOINT_NAME="galaxy-morph-dev-galaxy-classifier" ./services/emr/jobs/streaming_classification/scripts/submit_dev_job.sh
Generar el header para la URL del WebSocket (reemplazar <ID_TOKEN> con el
token de Cognito):
node -e "
const token = '<ID_TOKEN>';
const host = '74kj3tugizdhtfwddntkzikzdm.appsync-api.us-east-2.amazonaws.com';
console.log(encodeURIComponent(Buffer.from(JSON.stringify({Authorization: token, host})).toString('base64')));
"Mensaje start para registrar la suscripcion (reemplazar <ID_TOKEN> y
<CLIENT_ID>):
{
"id": "sub1",
"type": "start",
"payload": {
"data": "{\"query\":\"subscription OnClassification($clientId: ID!) { onClassification(clientId: $clientId) { jobId clientId imageKey status classification { predictedClass confidence probabilities } errorMessage } }\",\"variables\":{\"clientId\":\"<CLIENT_ID>\"}}",
"extensions": {
"authorization": {
"Authorization": "<ID_TOKEN>",
"host": "74kj3tugizdhtfwddntkzikzdm.appsync-api.us-east-2.amazonaws.com"
}
}
}
}