Documentation & Getting Started
This documentation guides you through setting up and using ONDEMANDENV, providing the necessary details to get the platform operational and integrate your services.
Installation & Setup
Follow these steps to set up the ONDEMANDENV platform in your environment.
1. Environment Preparation
AWS Environment:
- AWS Organization: Set up an AWS Organization.
-
Two AWS Accounts: Within your organization, designate or create:
- A Central Account: This is where the core ONDEMANDENV platform engine will run.
- A Workspace Account (workspace0): The initial target for deployments, including the mandatory contractsLib enver.
- Hosted Zone: Create a public hosted zone in Route 53 within the Central Account. Choose a suitable domain name, for example: <your-chosen-name>.root.ondemandenv.link. Note this name, as you will need it later.
- Region: Decide on the primary AWS region (e.g., us-east-1). All initial setup resources should be in this region.
-
AWS CDK Bootstrap: Bootstrap CDK in both the Central Account and
the workspace0 account for your chosen region. Run:
# In Central Account context aws configure set region YOUR_REGION cdk bootstrap aws://CENTRAL_ACCOUNT_ID/YOUR_REGION # In workspace0 Account context aws configure set region YOUR_REGION cdk bootstrap aws://WORKSPACE0_ACCOUNT_ID/YOUR_REGION
- Cross-Account Trust: Configure the workspace0 account to trust the Central Account. Create an IAM role in workspace0 (e.g., OndemandenvDeployerRole) with AdministratorAccess (or a more restricted policy based on least privilege later) that the Central Account can assume. The trust policy should explicitly allow the role ARN that the ONDEMANDENV platform will use in the Central Account (this will be defined by the platform template).
- GitHub App Private Key Secret: Create a secret in AWS Secrets Manager within the Central Account. Choose a specific name for this secret (e.g., ondemandenv/github-app-private-key). You will store your GitHub App's private key here in the next step. Note this secret name (ghAppPrivateKeySecretName). The ONDEMANDENV platform template will require this name.
GitHub Environment:
- GitHub Organization: Ensure you have a GitHub Organization set up.
-
Private GitHub App: Create a new, private GitHub App owned by your organization.
- Download the generated private key (.pem file).
- Important: Store the contents of this private key file securely as a new version in the AWS Secrets Manager secret (ghAppPrivateKeySecretName) you created in the Central Account.
- Configure necessary permissions for the App (refer to ONDEMANDENV documentation for specifics, typically includes read access to code, metadata, and write access for issues, pull requests, workflows, checks, statuses, deployments).
- Leave the Webhook URL blank for now; you will update this after deploying the platform.
- Install this GitHub App on the specific repository you intend to use for your `contractsLib`.
-
`contractsLib` Repository: Create a repository within your GitHub Organization to
define your service contracts. This repository will contain your ONDEMANDENV build and enver
definitions.
- You can use `ondemandenv/odmd-contracts-sandbox` as an example structure.
- Ensure your repository includes necessary dependencies (like `@ondemandenv/odmd-contracts-base`) and build scripts (e.g., in `package.json`) to compile your TypeScript definitions. The `@ondemandenv/odmd-contracts-base` package provides the core interfaces and base classes that your specific `contractsLib` will implement and extend to define your system's architecture and integrate with the ONDEMANDENV platform.
- You will need to package your compiled contractsLib definition using npm pack. This generates a .tgz file.
2. Platform Deployment
-
Submit Information to ONDEMANDENV Service:
You will need to provide the following information to the ONDEMANDENV service team (e.g., via email
or a setup portal):
- Your packaged contractsLib definition file (.tgz).
- The name of the hosted zone you created (e.g., <your-chosen-name>.root.ondemandenv.link).
- Your AWS Central Account ID.
- The name you chose for the GitHub App private key secret (ghAppPrivateKeySecretName).
- The GitHub App ID.
-
Receive and Deploy Platform Template:
The ONDEMANDENV service team will use this information to prepare the core infrastructure template.
They will send back a CloudFormation template file (e.g., odmd--central-artifact.template.json).
Deploy this template into your Central Account using the AWS Console or CLI.
(Note: Parameter overrides might be required depending on the template structure.)aws cloudformation deploy \ --template-file path/to/odmd--central-artifact.template.json \ --stack-name odmd-central-platform \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \ --region YOUR_REGION
Important Notes on Resource Sharing:
- S3 Bucket for Artifacts: This stack will provision or configure an S3 bucket. This bucket is used by the platform (and potentially your CI/CD workflows) to store deployment artifacts like CloudFormation templates. Ensure its policy allows access as needed by the ONDEMANDENV service backend.
- SQS Queue for Notifications: The template configures integration with an SQS queue provided by the ONDEMANDENV service. Your deployed stack resources (e.g., Lambda functions) will poll or be triggered by messages from this queue to receive notifications or commands from the platform.
-
Configure GitHub App Webhook:
- Wait for the CloudFormation stack (odmd-central-platform or similar name based on the template) to complete deployment successfully.
- Within the stack outputs, find the output named GithubWebHookUrl (or similar).
- Go back to your GitHub App settings page on GitHub.
- Paste this URL into the "Webhook URL" field.
- Configure a Webhook secret if required by the platform template and enter it in the GitHub App settings.
- Ensure the webhook is set to "Active".
Once these steps are complete, the core ONDEMANDENV platform should be running in your Central Account and connected to your GitHub App. You can then proceed to the Core Workflow section to learn how to define and deploy your services.
Core Workflow & How-To Guide
Once the platform is running, here's the detailed workflow for defining, implementing, and managing a service Enver, incorporating common how-to tasks:
1. Define a New Service & its Envers in `contractsLib`
Architecture, dependencies, and target environments are defined centrally. Edit your organization's contractsLib repository (e.g., <your-org>/my-contracts-lib-repo).
Key Actions:
- Define Build Configuration (OdmdBuild<T>): For each type of Enver (CDK, Cmd, Docker) associated with a source repository, create an instance of OdmdBuild<T> (where T is OdmdEnverCdk, OdmdEnverCmd, etc.). Provide the githubRepoAlias, buildType, and any source paths/commands.
- Define Enver(s) (OdmdEnverCdk, etc.): For each specific branch/tag you want to manage, create an instance of the appropriate Enver class (e.g., new OdmdEnverCdk(...)). Link it to the corresponding OdmdBuild instance. Specify the target AWS account alias (targetAccountAlias) and region (targetRegion). Use the Enver construct ID (e.g., 'OrderManagerDev') to represent the logical environment (often related to the branch name). Mark production/staging Envers as immutable (immutable: true) if they correspond to Git tags.
- Declare Single Product (Convention): Within the Enver definition, declare one primary Product (conventionally named 'Outputs') that will contain all shared outputs as a structured value (usually JSON). Example: outputsProduct: new Product(this, 'Outputs').
- Declare Consumers (How-To: Consume a Product): Within the Enver definition, declare dependencies on Products from other Envers using new Consumer(this, 'LocalConsumerName', otherEnver.outputsProduct, '{ /* Optional Default JSON */ }'). The 'LocalConsumerName' is how your CDK code will reference this consumed value (typically a JSON string). Ensure Tag Envers only consume from other Tag Envers. Default values (provided as a JSON string) can optionally be provided.
Example (my-org-contracts.ts):
// Example within your contractsLib repository (e.g., my-org-contracts.ts)
import { Construct } from 'constructs';
// Import base classes from the correct base library
import { OdmdContracts, OdmdBuild, OdmdEnverCdk, OdmdEnverCmd, Product, Consumer } from '@ondemandenv/odmd-contracts-base';
// Import other Enver definitions if needed for dependency references
// import { FoundationEnver } from './foundation-stack'; // Assuming Foundation publishes products
// Your main contracts class extends OdmdContracts
export class MyOrgContracts extends OdmdContracts {
constructor(scope: Construct, id: string) {
super(scope, id);
// --- Foundational Build/Enver (Example - Assuming it exists and has 'Outputs' product) ---
// const foundationBuild = new OdmdBuild(...) // Define build for FoundationEnver type
// const foundationDev = new FoundationEnver(this, 'FoundationDev', { build: foundationBuild, ... });
// const foundationProd = new FoundationEnver(this, 'FoundationProd', { build: foundationBuild, immutable: true, ... });
// --- Build Configuration for the 'npm' Commands Enver (example for contractsLib itself) ---
const npmCmdsBuild = new OdmdBuild(this, 'odmd-contracts-npm-CmdsGH', {
githubRepoAlias: 'my-contracts-lib-repo', // Alias for THIS contractsLib repo
buildType: 'cmd', // Uses custom commands
buildCommand: 'npm run build && npm pack',
});
// --- Enver for the 'npm' Commands (example: deploying to workspace0) ---
// Enver ID ('us-east-1-workspace0') often combines region and account alias
const npmCmdsDev = new OdmdEnverCmd(this, 'us-east-1-workspace0', {
build: npmCmdsBuild, // Link to the build config
targetAccountAlias: 'workspace0',
targetRegion: 'us-east-1',
// Typically no product/consumer for a simple command runner like this
});
// --- Build Configuration for Order Manager Service (CDK type) ---
const orderManagerBuild = new OdmdBuild(this, 'OrderManagerBuild', {
githubRepoAlias: 'order-manager-service', // Alias for the service repo
buildType: 'cdk',
sourcePath: 'infra/' // Path to CDK app within the repo
});
// --- Enver Definition for Order Manager 'dev' Branch ---
const orderManagerDev = new OdmdEnverCdk(this, 'OrderManagerDev', {
build: orderManagerBuild, // Link to the build config
targetAccountAlias: 'workspace0', // Deploying to workspace0 in example
targetRegion: 'us-east-1',
immutable: false, // Branch Enver
// Product published by this Enver (convention: single 'Outputs' product)
outputsProduct: new Product(this, 'Outputs'),
// Consumers (Example)
// Note: Use otherEnver.outputsProduct to reference the dependency's output product
// Example Consumer with a default value (JSON string)
// Assuming userPoolDev is another Enver defined elsewhere with an 'outputsProduct'
userPoolOutputsConsumer: new Consumer(this, 'UserPoolOutputs', /* userPoolDev.outputsProduct */ undefined,
'{ "userPoolId": "default-pool-id", "userPoolClientId": "default-client-id" }' // Default JSON string
),
// Example Consumer without default (will fail deployment if foundationDev dependency unavailable)
// foundationOutputsConsumer: new Consumer(this, 'FoundationOutputs', foundationDev.outputsProduct),
});
// --- Enver Definition for Order Manager 'prod' Tag (Immutable) ---
const orderManagerProd = new OdmdEnverCdk(this, 'OrderManagerProd', {
build: orderManagerBuild, // Link to the build config
targetAccountAlias: 'workspace0', // Example: deploying prod to workspace0 too
targetRegion: 'us-east-1',
immutable: true, // Tag Enver
// Product published by this Enver (convention: single 'Outputs' product)
outputsProduct: new Product(this, 'Outputs'),
// Consumers (Must consume from other *immutable* Envers)
// Assuming foundationProd is an immutable Enver defined elsewhere
// foundationOutputsConsumer: new Consumer(this, 'FoundationOutputs', foundationProd.outputsProduct),
});
// ... Define other builds/envers ...
}
}
Commit, PR, Merge: Follow standard Git workflow for the contractsLib repo.
Platform Synchronization: Merging triggers the contractsLib pipeline, which publishes updates and notifies the platform. The platform then generates/updates the specific CI/CD workflow file (e.g., .github/workflows/ODMD_OrderManagerDev_*.yaml) in the service repository (order-manager-service).
2. Implement the Service (CDK Stack / Dockerfile / Script)
In the service's repository (e.g., order-manager-service), implement the logic and infrastructure definitions.
How-To: Consume a Product in CDK
Within your CDK stack class (extending OdmdEnverCdk from @ondemandenv/odmd-contracts-base), use the static method OdmdEnverCdk.getSharedValue('LocalConsumerName') to retrieve the concrete value (typically a JSON string) during synthesis. The 'LocalConsumerName' must match the ID given in the Consumer definition in `contractsLib`. You will likely need to parse this JSON string to access individual values.
How-To: Publish a Product from CDK
Instantiate the single allowed OdmdShareOut construct per stack (from @ondemandenv/odmd-contracts-base). To publish multiple values, structure them as an object, serialize it to JSON using cdk.Stack.of(this).toJsonString(...), and publish the string. The ID used for OdmdShareOut (e.g., 'Outputs') MUST match the corresponding Product ID declared in `contractsLib`.
// Example: order-manager-service/infra/lib/order-manager-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as lambdaNode from 'aws-cdk-lib/aws-lambda-nodejs'; // For simplified Node.js Lambda bundling
import * as apigw from 'aws-cdk-lib/aws-apigateway';
import * as path from 'path';
// Ensure this import reflects your setup for the base library
import { OdmdEnverCdk, OdmdShareOut } from '@ondemandenv/odmd-contracts-base';
// Interface for parsed UserPool outputs (example)
interface UserPoolOutputs {
userPoolId: string;
userPoolClientId: string;
}
// Your stack extends the base OdmdEnverCdk class
export class OrderManagerStack extends OdmdEnverCdk {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// --- Consume structured values defined as Consumers in contractsLib ---
// Retrieve the JSON string using the local consumer name
const userPoolOutputsJson = OdmdEnverCdk.getSharedValue('UserPoolOutputs');
// Parse the JSON string to access individual properties (add error handling as needed)
const userPoolOutputs: UserPoolOutputs = JSON.parse(userPoolOutputsJson || '{}');
const userPoolId = userPoolOutputs.userPoolId; // Example access
// --- Create resources specific to this Enver ---
const orderQueue = new sqs.Queue(this, 'OrderQueue', {
// Provide a unique name based on the Enver ID suffix
queueName: `order-manager-queue-${OdmdEnverCdk.getEnverIdSuffix()}.fifo`, // Example: FIFO queue
fifo: true,
retentionPeriod: cdk.Duration.days(4),
// encryption: sqs.QueueEncryption.KMS_MANAGED, // Consider encryption
});
// Example using NodejsFunction for easier bundling
const orderHandlerLambda = new lambdaNode.NodejsFunction(this, 'OrderHandlerLambda', {
// Adjust path relative to CDK app root (e.g., infra/)
entry: path.join(__dirname, '../../src/lambda/order-handler.ts'), // Example path to lambda code
runtime: lambda.Runtime.NODEJS_LATEST, // Specify runtime
handler: 'handler', // Function entry point
bundling: { // Example bundling options
minify: true,
externalModules: ['@aws-sdk/*'], // Exclude AWS SDK v3 if using Lambda layer or built-in
},
environment: {
// Use consumed & parsed values if needed
USER_POOL_ID: userPoolId,
QUEUE_URL: orderQueue.queueUrl,
}
// ... potentially configure VPC, memorySize, timeout etc. ...
});
// Grant lambda permissions to interact with queue
orderQueue.grantSendMessages(orderHandlerLambda);
// Grant other permissions as needed (e.g., DynamoDB access)
// Example API Gateway
const api = new apigw.RestApi(this, 'OrderManagerApi', {
restApiName: `order-manager-api-${OdmdEnverCdk.getEnverIdSuffix()}`,
description: `API for Order Manager (${OdmdEnverCdk.getEnverIdSuffix()})`,
deployOptions: {
stageName: 'v1', // Example stage name
},
// defaultCorsPreflightOptions: { ... } // Consider CORS
});
// Define API resources and methods
const ordersResource = api.root.addResource('orders');
ordersResource.addMethod('POST', new apigw.LambdaIntegration(orderHandlerLambda));
// --- Structure and Publish Outputs via the SINGLE OdmdShareOut ---
// 1. Create an object containing the outputs you want to share
const outputsObject = {
apiUrl: api.url,
apiId: api.restApiId,
queueArn: orderQueue.queueArn,
queueUrl: orderQueue.queueUrl,
handlerLambdaArn: orderHandlerLambda.functionArn,
// Add other relevant outputs here
};
// 2. Use the SINGLE OdmdShareOut construct to publish the JSON string
// The second argument ('Outputs') MUST match the Product ID in contractsLib
new OdmdShareOut(this, 'Outputs', {
value: cdk.Stack.of(this).toJsonString(outputsObject)
});
}
}
```
3. Deploy & Iterate
Once your service is implemented, you can deploy it to the target environment. The platform automates the deployment process based on Git events and dependency updates.
Key Actions & Triggers:
- Code Change Trigger: Pushing commits to a branch in the service repository triggers
the deployment pipeline **if** that branch corresponds to a Branch Enver defined in
contractsLib
(e.g., pushing todev
triggers the 'ServiceNameDev' Enver pipeline). - Dependency Update Trigger: If an Enver consumes a Product from another Enver (Producer), an update to that consumed Product (i.e., the Producer deploys a new version) will automatically trigger a deployment of the consuming Enver to ensure it uses the latest dependency version.
- Monitoring Deployment: Monitor the deployment process (triggered by any of the above) in the GitHub Actions tab (or your configured CI/CD system) of the service repository.
- Verification: Verify the successful deployment by checking the AWS CloudFormation stack status and relevant resources in the target account, or by interacting with the deployed service endpoint.
- Iteration: Continue iterating by pushing code changes, which will trigger subsequent automated deployments.
4. Clone an Enver
You can clone an existing Enver to create a new one with a different configuration or target environment. This is useful for creating a staging environment, testing new features, or deploying to a different AWS account.
Key Actions:
- Define Clone in `contractsLib`: In your contractsLib repository, define a new Enver that clones an existing one. Specify the source Enver, the new target environment, and any additional configuration.
- Trigger Cloning: Trigger the cloning process by merging the changes into the contractsLib repository.
- Monitor Cloning: Monitor the cloning process in the GitHub Actions tab of the contractsLib repository.
- Verify Cloning: Verify the successful cloning by checking the AWS CloudFormation stack in the target account.
5. Delete a Clone
When you no longer need a cloned Enver, you can delete it to clean up resources and avoid unnecessary costs.
Key Actions:
- Remove from `contractsLib`: In your contractsLib repository, remove the definition of the cloned Enver.
- Trigger Deletion: Trigger the deletion process by merging the changes into the contractsLib repository.
- Monitor Deletion: Monitor the deletion process in the GitHub Actions tab of the contractsLib repository.
- Verify Deletion: Verify the successful deletion by checking that the AWS CloudFormation stack has been deleted in the target account.
Dynamic/Ephemeral Cloning
In addition to static clones defined in contractsLib, ONDEMANDENV supports dynamic, ephemeral cloning for rapid development and testing. These clones are temporary environments that can be created and destroyed on-demand.
Method 1: Manual Clone Commands
Create dynamic clones using special commands in Git commit messages:
Creating a Dynamic Clone:
- Create Feature Branch: Create a new feature branch from your base branch:
git checkout -b feature/new-feature # Make your code changes git add . git commit -m "Implement new feature odmd: create@myServiceDev"
- Push to Trigger Clone: Push your branch to trigger the platform:
git push origin feature/new-feature
- Platform Creates Clone: ONDEMANDENV automatically:
- Creates a dynamic Enver for your feature branch
- Inherits dependency versions from the source Enver
- Deploys isolated infrastructure with unique resource names
- Provides endpoints for your isolated environment
Deleting a Dynamic Clone:
git commit --allow-empty -m "Cleanup feature environment
odmd: delete"
git push origin feature/new-feature
Method 2: Automated PR-Based Cloning
ONDEMANDENV provides fully automated cloning that integrates seamlessly with Pull Request workflows:
Automated Workflow:
- Create Feature Branch & Push: Create and push your feature branch as usual:
git checkout -b feature/user-dashboard # Make your changes git commit -m "Redesign user dashboard" git push origin feature/user-dashboard
- Create Pull Request: Create a PR targeting a branch with a static Enver:
gh pr create --base dev --head feature/user-dashboard \ --title "User Dashboard Redesign" \ --body "Implements new responsive design"
- Automatic Clone Creation: When the PR targets a branch with a static Enver in contractsLib, the platform automatically:
- Detects the PR creation
- Creates a dynamic Enver for the PR branch
- Deploys the isolated environment
- Updates the PR with environment details
- Automatic Updates: Additional commits to the PR branch automatically update the dynamic environment
- Automatic Cleanup: When the PR is closed or merged, the platform automatically destroys the dynamic Enver and cleans up all resources
Benefits of Dynamic Cloning:
- Isolated Testing: Each feature gets its own complete environment
- Dependency Consistency: Clones inherit exact dependency versions from source Envers
- Resource Isolation: Unique resource naming prevents conflicts
- Automatic Cleanup: No forgotten environments consuming resources (especially with PR-based method)
- Rapid Iteration: Quick environment provisioning for fast feedback cycles
- Full Stack Testing: Complete infrastructure and application testing in isolation
Requirements for PR-Based Automation:
- Static Enver Mapping: Target branch must have a corresponding static Enver in contractsLib
- GitHub App Permissions: Platform needs appropriate permissions to monitor PR events
- Branch Name Matching: PR target branch names must match Git branch references in static Enver definitions
Comparison of Dynamic Cloning Methods:
Aspect | Manual Commands | PR-Based Automation |
---|---|---|
Trigger | odmd: create@ in commit | PR creation against static Enver branch |
Cleanup | odmd: delete in commit | PR closure (merge/close) |
Use Case | Ad-hoc testing, experimentation | Standard development workflow |
Automation Level | Manual control | Fully automated |
Integration | Git commits | GitHub/GitLab workflow |
Use Platform Services
The ONDEMANDENV platform provides additional services to enhance your development and deployment experience.
Key Services:
- ONDEMANDENV Console: A web-based interface that visualizes your environments, builds, and their relationships. It provides real-time versioning information, status monitoring, and Enver details. Access it at web.auth.ondemandenv.link.
- CI/CD Integration: Seamless integration with your preferred CI/CD tools (e.g., GitHub Actions) to automate the deployment process.
- Isolated Testing: Isolate your tests in dedicated environments to ensure they don't interfere with production or other development efforts.
- Shared Networking: Share networking resources across Envers to optimize costs and improve performance.
- Shared EKS: Share a single Elastic Kubernetes Service (EKS) cluster across multiple Envers for better resource utilization and cost savings.
Deployment Model
The ONDEMANDENV platform follows a unique deployment model that combines the benefits of both monolithic and microservices architectures.
Key Concepts:
- Envers: An Enver represents a logical environment or version of a service. It can be a branch, a tag, or a specific configuration. Envers are defined in the contractsLib repository.
- Builds: A build is the process of packaging and preparing the service for deployment. Builds are defined in the contractsLib repository.
- Producers & Consumers: Producers are Envers that publish shared outputs (products) that other Envers (consumers) can consume. This enables a modular and decoupled architecture.
- Deployment Workflow: The platform automates the deployment process, including building the service, packaging the artifacts, and deploying the infrastructure.
Benefits:
- Modularity: Services are decoupled and modular, allowing for independent development and deployment.
- Isolation: Envers are isolated from each other, ensuring that changes in one environment don't affect others.
- Scalability: The platform can handle a large number of Envers and builds, supporting both small and large-scale deployments.
- Flexibility: Envers can be cloned to create new environments with different configurations or targets.
- Cost Optimization: Shared resources and infrastructure can lead to cost savings compared to traditional microservices architectures.
Security Considerations
Security is a top priority in the ONDEMANDENV platform. Here are some key security considerations:
Access Control:
- Role-Based Access Control (RBAC): Fine-grained access control is implemented using IAM roles and policies.
- Least Privilege: Principals are granted the minimum permissions necessary to perform their tasks.
- Separation of Duties: Different roles are responsible for different aspects of the platform, reducing the risk of unauthorized access.
Data Protection:
- Encryption at Rest: Sensitive data is encrypted at rest using AWS Key Management Service (KMS).
- Encryption in Transit: Data is encrypted in transit using SSL/TLS.
- Data Isolation: Envers are isolated from each other, ensuring that data from one environment doesn't leak into another.
Infrastructure Security:
- Network Isolation: Envers are isolated using VPCs, subnets, and security groups.
- Intrusion Detection: AWS services like AWS GuardDuty and AWS Inspector are used for intrusion detection and vulnerability scanning.
- Patch Management: Automated patch management is implemented using AWS Systems Manager.
Compliance:
- SOX Compliance: The platform is designed to meet the requirements of the Sarbanes-Oxley Act (SOX).
- HIPAA Compliance: The platform is designed to meet the requirements of the Health Insurance Portability and Accountability Act (HIPAA).
- PCI DSS Compliance: The platform is designed to meet the requirements of the Payment Card Industry Data Security Standard (PCI DSS).
CI/CD Integration
The ONDEMANDENV platform integrates seamlessly with your preferred CI/CD tools to automate the deployment process.
Key Features:
- GitHub Actions: The platform is designed to work with GitHub Actions, allowing you to define and automate your CI/CD workflows directly in your contractsLib repository.
- Customizable Workflows: You can customize the CI/CD workflows to meet your specific needs, including testing, building, and deploying.
- Integration with ONDEMANDENV Console: The CI/CD workflows are integrated with the ONDEMANDENV Console, providing real-time visibility into the deployment process.
- Isolated Testing: The platform supports isolated testing environments, ensuring that your tests don't interfere with production or other development efforts.
Example Workflow:
- Trigger: A change is merged into the dev branch of the service repository.
- Build: The CI/CD workflow is triggered, and the service is built using the specified build configuration.
- Test: The service is tested in an isolated environment to ensure it functions correctly.
- Deploy: If the tests pass, the service is deployed to the dev Enver.
- Notify: The ONDEMANDENV Console is notified of the successful deployment, and the status is updated.
Base Library
The ONDEMANDENV platform provides a crucial base library, published as @ondemandenv/odmd-contracts-base
. This library is fundamental to the platform's operation, serving as the definitive contract between all user-defined builds/envers and the central ONDEMANDENV system. It supplies the essential TypeScript base classes and interfaces that your organization's contractsLib
repository will use.
When you create your own contractsLib
(like the example odmd-contracts-sandbox
), you will extend these base classes. This extension mechanism is key to how the platform understands your architecture and, critically, how your specific services (including custom console implementations) bridge to the central platform's capabilities, such as AWS AppSync for real-time data synchronization.
For instance, a common pattern is for a user-defined contract for console authentication, like OdmdBuildUserAuthSbx.ts
from the sandbox, to extend a corresponding base class from odmd-build-user-auth.ts
in @ondemandenv/odmd-contracts-base
. This ensures that your implementation correctly interacts with the platform's expectations for authentication and data exchange with services like AppSync.
Key Features:
- TypeScript: The base library is written in TypeScript, providing strong typing and improved developer experience.
- Extensible: The library is designed to be extensible, allowing you to customize and extend its functionality as needed.
- Modular: The library is modular, with separate modules for different aspects of the platform, such as contracts, builds, and Envers.
- Documentation: The library is well-documented, with detailed API documentation and examples.
Example Usage:
// Example usage of the base library
import { Construct } from 'constructs';
import { OdmdContracts, OdmdBuild, OdmdEnverCdk, Product, Consumer } from '@ondemandenv/odmd-contracts-base';
export class MyServiceContracts extends OdmdContracts {
constructor(scope: Construct, id: string) {
super(scope, id);
const myServiceBuild = new OdmdBuild(this, 'MyServiceBuild', {
githubRepoAlias: 'my-service-repo',
buildType: 'cdk',
sourcePath: 'infra/',
});
const myServiceDev = new OdmdEnverCdk(this, 'MyServiceDev', {
build: myServiceBuild,
targetAccountAlias: 'workspace0',
targetRegion: 'us-east-1',
immutable: false,
outputsProduct: new Product(this, 'Outputs'),
});
const myServiceProd = new OdmdEnverCdk(this, 'MyServiceProd', {
build: myServiceBuild,
targetAccountAlias: 'workspace0',
targetRegion: 'us-east-1',
immutable: true,
outputsProduct: new Product(this, 'Outputs'),
});
}
}
Explore the Code
The ONDEMANDENV platform is open source, and its code is available on GitHub. You can explore the code and contribute to its development.
Key Repositories:
- Platform Core: github.com/ondemandenv/odmd-platform-core
- Base Library: github.com/ondemandenv/odmd-contracts-base
- Example Contracts: github.com/ondemandenv/odmd-contracts-sandbox
Contributing:
We welcome contributions to the ONDEMANDENV platform. If you're interested in contributing, please review our Contributing Guidelines.
Platform Internals
This section provides an overview of the internal workings of the ONDEMANDENV platform.
Architecture:
The platform is built on a microservices architecture, with separate services responsible for different aspects of the platform. The main services include:
- Contracts Service: Manages the contractsLib repository and generates the CI/CD workflows.
- Build Service: Builds the service artifacts based on the build configuration.
- Deployment Service: Deploys the service artifacts to the target environment.
- Console Service: Provides the ONDEMANDENV Console web interface.
Data Flow:
The data flow within the platform is as follows:
- Contracts: The contractsLib repository defines the contracts for the platform, including the build configurations and Enver definitions.
- CI/CD Workflows: The Contracts Service generates the CI/CD workflows based on the contracts.
- Build: The Build Service builds the service artifacts based on the build configuration.
- Deployment: The Deployment Service deploys the service artifacts to the target environment.
- Console: The Console Service provides real-time visibility into the platform, including the status of Envers and the relationships between them.
Security:
The platform implements various security measures to ensure the confidentiality, integrity, and availability of the data and services. For more details, refer to the Security Considerations section.
Scalability:
The platform is designed to scale horizontally, allowing it to handle a large number of Envers and builds. The services are stateless and can be scaled independently based on the workload.
Reliability:
The platform is designed to be highly reliable, with redundant components and automated failover mechanisms. The services are deployed across multiple availability zones to ensure high availability.
ONDEMANDENV Console
Overview
The ONDEMANDENV Console serves as the primary user interface for visualizing and interacting with your environments, builds, and their relationships within the platform. After logging in (typically via Google OAuth integrated with your organization's identity provider), the console connects securely to the central AppSync API in your AWS environment.
Its main focus is to provide clarity on the complex web of dependencies inherent in distributed systems,
leveraging the information codified in your contractsLib
.
Console Authentication Setup
To enable user authentication for the console, you will need to configure Google OAuth 2.0. This process involves:
- Setting up an OAuth 2.0 client ID in the Google Cloud Console.
- Obtaining a Google Client ID and a Google Client Secret.
- These credentials must then be securely incorporated into your
contractsLib
definitions. This typically involves referencing them as secure parameters or secrets that the console's backend infrastructure (defined via an Enver incontractsLib
) can access. - For an example of how these credentials are referenced within
contractsLib
for a user authentication service that the console would rely on, see theOdmdBuildUserAuthSbx.ts
example in the sandbox contracts. This example file typically extends a base authentication contract class (e.g.,odmd-build-user-auth.ts
) from the@ondemandenv/odmd-contracts-base
library, demonstrating how your specific console authentication setup connects with the central platform logic, often involving services like AWS AppSync.
Proper configuration of these OAuth credentials and their integration into your contractsLib
is essential for the console's login functionality and secure access to real-time data.
Key Features
- Dependency Visualization: Clearly shows how builds (producers) and Envers
(consumers) depend on each other, based on the contracts defined in
contractsLib
. - Real-time Versioning Information: Connects to AWS AppSync in the central account to fetch live data about all producer build versions and consumer Enver deployments.
- Status Monitoring: Indicates whether a consumer Enver is using an up-to-date version of a producer build, is lagging behind, or if a required dependency hasn't been deployed yet.
- Enver Details: Displays specific details for each Enver, such as the exact version
of the
contractsLib
it's using, derived from real-time AWS Stack summaries. - Secure Access: Uses Google OAuth for authentication, ensuring only authorized users can access the console and system data.
Example Access
You can explore a live example of the ONDEMANDENV console configured for the demonstration organization hosted on GitHub (github.com/ondemandenv). Access it here:
Example Console (web.auth.ondemandenv.link)
Note: Access to specific data within the example console may require appropriate permissions tied to the example organization's authentication setup.
Support
If you need help or have any questions about the ONDEMANDENV platform, please don't hesitate to reach out to our support team.
Contact Information:
- Email: support@ondemandenv.dev
Additional Resources:
- Documentation: ONDEMANDENV Documentation
- GitHub: ONDEMANDENV GitHub Organization