container-image-scanner
Version:
šØ EMERGENCY Bitnami Migration Scanner - Critical Timeline Aug 28/Sep 29, 2025. Enterprise scanner for 280+ Bitnami images, 118+ Helm charts with emergency migration automation to AWS alternatives.
328 lines (291 loc) ⢠11 kB
JavaScript
const chalk = require('chalk');
class BitnamiMappingStrategy {
constructor() {
// Based on official Bitnami repositories:
// https://github.com/bitnami/containers/tree/main/bitnami
// https://github.com/bitnami/charts/tree/main/bitnami
this.mappingStrategy = {
// Databases - AWS Managed Services FIRST
'mysql': {
awsManaged: 'Amazon RDS for MySQL',
upstream: 'mysql:8.0',
partnerAvailable: true,
partnerNote: 'PlanetScale available on AWS Marketplace'
},
'postgresql': {
awsManaged: 'Amazon RDS for PostgreSQL',
upstream: 'postgres:15',
partnerAvailable: true,
partnerNote: 'Multiple PostgreSQL partners on AWS Marketplace'
},
'mongodb': {
awsManaged: 'Amazon DocumentDB (MongoDB-compatible)',
upstream: 'mongo:6.0',
partnerAvailable: true,
partnerNote: 'MongoDB Atlas available on AWS Marketplace'
},
'redis': {
awsManaged: 'Amazon ElastiCache for Redis',
upstream: 'redis:7.2',
partnerAvailable: true,
partnerNote: 'Redis Enterprise available on AWS Marketplace'
},
'mariadb': {
awsManaged: 'Amazon RDS for MariaDB',
upstream: 'mariadb:10.11',
partnerAvailable: false
},
'memcached': {
awsManaged: 'Amazon ElastiCache for Memcached',
upstream: 'memcached:1.6',
partnerAvailable: false
},
// Analytics & Search - AWS Managed Services FIRST
'elasticsearch': {
awsManaged: 'Amazon OpenSearch Service',
upstream: 'elasticsearch:8.8.0',
partnerAvailable: true,
partnerNote: 'Elastic Cloud available on AWS Marketplace'
},
'opensearch': {
awsManaged: 'Amazon OpenSearch Service',
upstream: 'opensearchproject/opensearch:2.9',
partnerAvailable: false
},
'kibana': {
awsManaged: 'Amazon OpenSearch Dashboards',
upstream: 'kibana:8.8.0',
partnerAvailable: true,
partnerNote: 'Part of Elastic Cloud on AWS Marketplace'
},
// Monitoring - AWS Managed Services FIRST
'grafana': {
awsManaged: 'Amazon Managed Grafana',
upstream: 'grafana/grafana:10.0',
partnerAvailable: true,
partnerNote: 'Grafana Cloud available on AWS Marketplace'
},
'prometheus': {
awsManaged: 'Amazon Managed Service for Prometheus',
upstream: 'prom/prometheus:v2.45',
partnerAvailable: true,
partnerNote: 'Grafana Cloud includes Prometheus'
},
// Messaging & Streaming - AWS Managed Services FIRST
'kafka': {
awsManaged: 'Amazon MSK (Managed Streaming for Apache Kafka)',
upstream: 'confluentinc/cp-kafka:7.4',
partnerAvailable: true,
partnerNote: 'Confluent Platform available on AWS Marketplace'
},
'rabbitmq': {
awsManaged: 'Amazon MQ for RabbitMQ',
upstream: 'rabbitmq:3.12',
partnerAvailable: true,
partnerNote: 'CloudAMQP available on AWS Marketplace'
},
'zookeeper': {
awsManaged: 'Amazon MSK (includes managed Zookeeper)',
upstream: 'confluentinc/cp-zookeeper:7.4',
partnerAvailable: false
},
// Big Data & Analytics - AWS Managed Services FIRST
'spark': {
awsManaged: 'Amazon EMR',
upstream: 'apache/spark:3.4.1',
partnerAvailable: false
},
'airflow': {
awsManaged: 'Amazon MWAA (Managed Workflows for Apache Airflow)',
upstream: 'apache/airflow:2.7.0',
partnerAvailable: false
},
'jupyter': {
awsManaged: 'Amazon SageMaker Studio',
upstream: 'jupyter/scipy-notebook:latest',
partnerAvailable: false
},
// Web Servers & Load Balancers - AWS Services FIRST
'nginx': {
awsManaged: 'AWS Application Load Balancer + EKS',
upstream: 'nginx:1.25',
partnerAvailable: false,
note: 'For load balancing use ALB; for web server keep nginx upstream'
},
'apache': {
awsManaged: 'AWS Application Load Balancer + EKS',
upstream: 'httpd:2.4',
partnerAvailable: false,
note: 'For load balancing use ALB; for web server keep apache upstream'
},
'haproxy': {
awsManaged: 'AWS Network Load Balancer',
upstream: 'haproxy:2.8',
partnerAvailable: false
},
// Development Runtimes - AWS Services FIRST
'node': {
awsManaged: 'AWS Lambda (Node.js runtime)',
upstream: 'node:18-alpine',
partnerAvailable: false,
note: 'For serverless use Lambda; for containers use upstream'
},
'python': {
awsManaged: 'AWS Lambda (Python runtime)',
upstream: 'python:3.11-alpine',
partnerAvailable: false,
note: 'For serverless use Lambda; for containers use upstream'
},
// CI/CD & DevOps - AWS Services FIRST
'jenkins': {
awsManaged: 'AWS CodeBuild + CodePipeline',
upstream: 'jenkins/jenkins:lts',
partnerAvailable: false,
note: 'AWS CodeBuild recommended for CI/CD'
},
'sonarqube': {
awsManaged: 'Amazon CodeGuru Reviewer',
upstream: 'sonarqube:community',
partnerAvailable: true,
partnerNote: 'SonarCloud available on AWS Marketplace'
},
// Container Registry
'registry': {
awsManaged: 'Amazon ECR (Elastic Container Registry)',
upstream: 'registry:2',
partnerAvailable: false
},
// Security & Identity
'keycloak': {
awsManaged: 'Amazon Cognito',
upstream: 'keycloak/keycloak:22.0',
partnerAvailable: false,
note: 'Cognito for authentication; Keycloak for complex identity management'
},
'vault': {
awsManaged: 'AWS Secrets Manager + AWS Systems Manager Parameter Store',
upstream: 'vault:1.14',
partnerAvailable: true,
partnerNote: 'HashiCorp Vault available on AWS Marketplace'
}
};
}
analyzeImage(imageName) {
const [name, tag] = imageName.split(':');
const service = name.split('/')[1]?.split(':')[0];
if (!name.includes('bitnami')) {
return { applicable: false };
}
const mapping = this.mappingStrategy[service];
if (!mapping) {
return {
applicable: true,
imageName,
service,
mapped: false,
recommendation: 'Check AWS services or consider upstream alternative'
};
}
return {
applicable: true,
imageName,
service,
mapped: true,
awsManaged: mapping.awsManaged,
upstream: mapping.upstream,
partnerAvailable: mapping.partnerAvailable,
partnerNote: mapping.partnerNote,
note: mapping.note,
isVersioned: tag && tag !== 'latest' && /^\d+\.\d+/.test(tag)
};
}
generateMappingReport(images) {
console.log(chalk.bold.blue('šÆ Bitnami Migration Strategy'));
console.log(chalk.gray('AWS Managed ā Upstream ā Partners\n'));
const analyses = images.map(img => this.analyzeImage(img)).filter(a => a.applicable);
if (analyses.length === 0) {
console.log(chalk.yellow('No Bitnami images provided for analysis.'));
return;
}
const mapped = analyses.filter(a => a.mapped);
const unmapped = analyses.filter(a => !a.mapped);
// Show mapped services with strategy
if (mapped.length > 0) {
console.log(chalk.green.bold('ā
MIGRATION OPTIONS AVAILABLE'));
mapped.forEach(analysis => {
console.log(chalk.bold(`\nš¦ ${analysis.imageName}`));
console.log(` Version: ${analysis.isVersioned ? chalk.red('Pinned') : chalk.green('Latest')}`);
// AWS Managed Service (PRIMARY)
console.log(chalk.blue(' š„ AWS Managed Service (RECOMMENDED):'));
console.log(chalk.blue(` ${analysis.awsManaged}`));
// Upstream Open Source (ALTERNATIVE)
console.log(chalk.cyan(' š„ Upstream Open Source:'));
console.log(chalk.cyan(` ${analysis.upstream}`));
// Partner Options (IF AVAILABLE)
if (analysis.partnerAvailable) {
console.log(chalk.magenta(' š„ Partner Option:'));
console.log(chalk.magenta(` ${analysis.partnerNote}`));
} else {
console.log(chalk.gray(' š„ Partner Option: None identified'));
}
// Additional Notes
if (analysis.note) {
console.log(chalk.yellow(` š” Note: ${analysis.note}`));
}
});
}
// Show unmapped services
if (unmapped.length > 0) {
console.log(chalk.yellow.bold('\nā ļø SERVICES NEEDING ASSESSMENT'));
unmapped.forEach(analysis => {
console.log(` š¦ ${analysis.imageName}`);
console.log(` Service: ${analysis.service}`);
console.log(` ā ${analysis.recommendation}`);
});
}
// Summary statistics
console.log(chalk.bold('\nš Migration Strategy Summary:'));
console.log(` Total Bitnami Images: ${analyses.length}`);
console.log(` Have AWS Managed Alternative: ${chalk.green(mapped.length)}`);
console.log(` Have Partner Options: ${chalk.magenta(mapped.filter(a => a.partnerAvailable).length)}`);
console.log(` Need Assessment: ${chalk.yellow(unmapped.length)}`);
// Next steps
console.log(chalk.bold('\nšÆ Recommended Approach:'));
console.log(' 1. Evaluate AWS managed services first (cost, features, integration)');
console.log(' 2. Consider upstream open source for container workloads');
console.log(' 3. Explore partner solutions for specialized requirements');
console.log(' 4. Engage AWS Solutions Architect for complex scenarios');
}
getTotalMappings() {
return Object.keys(this.mappingStrategy).length;
}
}
// Test with official Bitnami images
if (require.main === module) {
const mapper = new BitnamiMappingStrategy();
console.log(chalk.bold.blue(`š Bitnami Mapping Strategy - ${mapper.getTotalMappings()} Services Mapped\n`));
const testImages = [
// From bitnami/containers repository
'bitnami/mysql:8.0.35',
'bitnami/postgresql:15.4.0',
'bitnami/mongodb:6.0.8',
'bitnami/redis:7.2.4',
'bitnami/elasticsearch:8.8.0',
'bitnami/grafana:10.0.3',
'bitnami/prometheus:2.45.0',
'bitnami/kafka:3.5.0',
'bitnami/rabbitmq:3.12.2',
'bitnami/nginx:1.25.2',
'bitnami/apache:2.4.57',
'bitnami/jenkins:2.414.1',
'bitnami/airflow:2.7.0',
'bitnami/spark:3.4.1',
'bitnami/keycloak:22.0.1',
'bitnami/vault:1.14.0',
// Unmapped example
'bitnami/custom-service:1.0.0'
];
mapper.generateMappingReport(testImages);
}
module.exports = { BitnamiMappingStrategy };