Skip to content

Service

A Service in Odin represents a deployable application unit composed of one or more components. Services are the primary abstraction for managing your applications in Odin.

A service is a functional unit with defined boundaries that:

  • Consists of one or more components (web servers, databases, caches, etc.)
  • Can be treated as a blackbox from the outside
  • Is versioned and can be deployed independently
  • Has lifecycle states and can be operated as a unit

Services are defined using JSON files with the following structure:

{
"name": "user-api",
"version": "1.0.0",
"team": "backend-team",
"components": [
{
"name": "api-server",
"type": "webservice",
"version": "2.1.0",
"depends_on": ["database", "cache"],
"config": {
"port": 8080,
"replicas": 3
}
},
{
"name": "database",
"type": "postgres",
"version": "14.5",
"config": {
"storage": "100Gi"
}
},
{
"name": "cache",
"type": "redis",
"version": "7.0",
"config": {
"memory": "2Gi"
}
}
]
}
PropertyDescription
nameUnique identifier for the service
versionSemantic version (e.g., 1.0.0, 1.2.0-SNAPSHOT)
teamOwning team or organization
componentsArray of component definitions

Deploy a service to an environment:

Terminal window
odin deploy service --env <env-name> \
--file service.json \
--provisioning provisioning.json

The deployment process:

  1. Validates the service definition
  2. Validates provisioning configuration
  3. Creates deployment tasks for each component
  4. Deploys components according to dependency order
  5. Monitors deployment status and reports progress

Services transition through several states during their lifecycle:

StateDescription
DEPLOYINGDeployment in progress
DEPLOYEDAll components successfully deployed
FAILEDOne or more components failed
UNDEPLOYINGTeardown in progress
UNDEPLOYEDService removed from environment

Check the status of a deployed service:

Terminal window
odin status env <env-name> --service <service-name>

Get detailed component-level information:

Terminal window
odin describe env <env-name> --service <service-name>

Remove a service from an environment:

Terminal window
odin undeploy service <service-name> --env <env-name>

Execute lifecycle operations on a service:

Terminal window
odin operate service --name <service-name> \
--env <env-name> \
--operation <operation-type> \
--options '{"key": "value"}'

Or use a file for operation parameters:

Terminal window
odin operate service --name <service-name> \
--env <env-name> \
--operation <operation-type> \
--file operation.json

Update a service with new configuration:

Terminal window
odin operate service --name user-api \
--env staging \
--operation redeploy \
--file updated-service.json

When redeploying, Odin shows a diff of pending changes and asks for confirmation.

Add a new component to an existing service:

Terminal window
odin operate service --name user-api \
--env staging \
--operation ADD_COMPONENT \
--options '{
"component_definition": {
"name": "cache",
"type": "redis",
"version": "7.0"
},
"provisioning_config": {
"component_name": "cache",
"deployment_type": "elasticache-redis"
}
}'

Remove a component from a service:

Terminal window
odin operate service --name user-api \
--env staging \
--operation REMOVE_COMPONENT \
--options '{"component_name": "old-cache"}'

Odin supports two versioning strategies:

Mutable versions for development and QA:

{
"name": "user-api",
"version": "1.2.0-SNAPSHOT",
...
}
  • Can be redeployed with changes
  • Ideal for fast iteration
  • Not suitable for production

Immutable versions for production:

{
"name": "user-api",
"version": "1.2.0",
...
}
  • Cannot be modified once released
  • Guarantees reproducibility
  • Suitable for production deployments
  1. Use Semantic Versioning: Follow major.minor.patch format
  2. Document Dependencies: Clearly specify depends_on relationships
  3. Modular Components: Break services into logical components
  4. Team Ownership: Assign clear team ownership
  1. Develop with SNAPSHOT: Deploy 1.0.0-SNAPSHOT to dev environment
  2. Iterate with QA: Test and refine in staging environment
  3. Release CONCRETE: Create 1.0.0 release for production
  4. Deploy to Production: Deploy immutable version to prod

Define dependencies correctly to ensure proper deployment order:

{
"components": [
{
"name": "api",
"depends_on": ["database", "cache"]
},
{
"name": "database",
"depends_on": []
},
{
"name": "cache",
"depends_on": []
}
]
}

Odin deploys in order: databasecacheapi

Use the config field for component-specific settings:

{
"name": "api-server",
"config": {
"port": 8080,
"replicas": 3,
"env": {
"LOG_LEVEL": "info",
"DB_POOL_SIZE": "20"
}
}
}
{
"name": "hello-world",
"version": "1.0.0-SNAPSHOT",
"team": "platform",
"components": [
{
"name": "web",
"type": "webservice",
"version": "1.0.0",
"config": {
"port": 8080
}
}
]
}
{
"name": "ecommerce-api",
"version": "2.1.0",
"team": "ecommerce",
"components": [
{
"name": "api",
"type": "webservice",
"version": "2.1.0",
"depends_on": ["database", "cache", "queue"],
"config": {
"port": 8080,
"replicas": 5
}
},
{
"name": "database",
"type": "postgres",
"version": "14.5",
"config": {
"storage": "200Gi",
"instance_class": "db.r5.large"
}
},
{
"name": "cache",
"type": "redis",
"version": "7.0",
"config": {
"memory": "4Gi"
}
},
{
"name": "queue",
"type": "rabbitmq",
"version": "3.11",
"config": {
"queues": ["orders", "notifications"]
}
}
]
}