Introduction to Spinnaker
Spinnaker is an open-source, multi-cloud continuous delivery platform created by Netflix and later co-developed with Google. It is designed to release software changes with high velocity and confidence across multiple cloud providers such as AWS, Google Cloud Platform, Microsoft Azure, Kubernetes, and more. Unlike traditional CI tools, Spinnaker focuses exclusively on continuous delivery (CD), enabling teams to orchestrate complex deployment pipelines, manage cloud resources, and implement progressive delivery strategies like blue/green and canary deployments.
Why Spinnaker Matters
Modern applications are deployed across distributed environments with frequent releases. Spinnaker matters because it decouples deployment from build, integrates natively with cloud providers, and provides a unified API for managing deployments. It reduces deployment risk through automated rollbacks, deployment windows, and granular approval workflows. For organizations scaling microservices, Spinnaker offers a battle-tested solution that has been proven at Netflix-scale.
Spinnaker Architecture Overview
Spinnaker is composed of several microservices, each responsible for a specific function. Understanding these components is essential before configuring the platform.
- Clouddriver: Interacts with cloud providers and maintains a cached view of cloud resources.
- Deck: The browser-based UI for managing pipelines and deployments.
- Gate: The API gateway that authenticates and routes requests to backend services.
- Orca: The orchestration engine that executes pipelines and stages.
- Front50: The persistence service that stores application, pipeline, and strategy metadata.
- Rosco: The bakery service that builds immutable machine images using Packer.
- Igor: Integrates with CI systems like Jenkins and Git for triggering pipelines.
- Fiat: The authorization service that manages user roles and permissions.
- Kayenta: The automated canary analysis service.
Installing Spinnaker
The fastest way to install Spinnaker is using Halyard, the official command-line administration tool. Halyard manages the configuration and lifecycle of your Spinnaker deployment.
Installing Halyard
On a Linux or macOS machine, install Halyard with the following commands:
curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/debian/InstallHalyard.sh
sudo bash InstallHalyard.sh
hal --version
After installation, verify that Halyard is running:
hal --version
Choosing a Storage Provider
Spinnaker requires a persistent storage backend to store application and pipeline metadata. Supported options include Amazon S3, Google Cloud Storage, Azure Blob Storage, and Minio. For this guide, we will use S3.
hal config storage s3 edit \
--endpoint https://s3.amazonaws.com \
--bucket my-spinnaker-bucket \
--access-key-id YOUR_ACCESS_KEY \
--secret-access-key YOUR_SECRET_KEY
hal config storage edit --type s3
Configuring Cloud Providers
Spinnaker supports multiple cloud providers. You must enable and configure at least one provider to deploy applications.
Configuring Kubernetes
Kubernetes is the most common provider for modern Spinnaker deployments. First, enable the Kubernetes provider:
hal config provider kubernetes enable
Next, add a Kubernetes account. You will need a kubeconfig file with access to your cluster:
hal config provider kubernetes account add my-k8s-account \
--context my-cluster-context \
--kubeconfig-file ~/.kube/config \
--only-spinnaker-managed true \
--namespaces default,production,staging
hal config provider kubernetes account delete default
The --only-spinnaker-managed flag ensures Spinnaker only modifies resources it created, preventing accidental changes to manually created resources.
Configuring AWS
To deploy to AWS, enable the AWS provider and configure an account with appropriate credentials:
hal config provider aws enable
hal config provider aws account add my-aws-account \
--access-key-id YOUR_ACCESS_KEY \
--secret-access-key YOUR_SECRET_KEY \
--regions us-east-1,us-west-2
hal config provider aws bakery edit \
--aws-access-key-id YOUR_ACCESS_KEY \
--aws-secret-access-key YOUR_SECRET_KEY \
--aws-default-region us-east-1
Deploying Spinnaker
Once your storage and cloud providers are configured, you need to choose a deployment environment. Spinnaker can be deployed to a local machine, a distributed environment, or Kubernetes.
Deploying to Kubernetes
For production deployments, Kubernetes is recommended. Configure Halyard to deploy Spinnaker to Kubernetes:
hal config deploy edit --type distributed --account-name my-k8s-account
Set the Spinnaker version you want to deploy:
hal config version edit --version 1.33.0
Finally, deploy Spinnaker:
hal deploy apply
This command generates Kubernetes manifests and applies them to your cluster. Monitor the deployment with:
kubectl get pods -n spinnaker
Configuring Authentication and Authorization
For production deployments, you must secure Spinnaker with authentication and role-based access control.
Configuring GitHub OAuth
Spinnaker supports multiple identity providers. To configure GitHub OAuth, first create an OAuth application in GitHub, then configure Gate:
hal config security authn oauth2 edit \
--client-id YOUR_GITHUB_CLIENT_ID \
--client-secret YOUR_GITHUB_CLIENT_SECRET \
--provider github \
--pre-established-redirect-uri https://spinnaker.example.com/login
hal config security authn oauth2 enable
Configuring RBAC with Fiat
Role-based access control is managed by Fiat. Enable Fiat and configure role providers:
hal config security authz enable
hal config security authz github edit \
--organization my-organization \
--access-organization my-organization
hal deploy apply
You can then define role-based permissions in a YAML file:
roles:
- name: developers
description: Development team members
- name: ops
description: Operations team members
policies:
- name: developer-policy
description: Read-only access to applications
role: developers
permissions:
- resource: application:my-app
actions: READ
- name: ops-policy
description: Full access to applications
role: ops
permissions:
- resource: application:my-app
actions: READ,WRITE,EXECUTE
Creating Applications and Pipelines
Applications are the top-level organizational unit in Spinnaker. Each application contains pipelines that define deployment workflows.
Creating an Application
You can create an application through the Deck UI or via the API. Here is an example using the API:
curl -X POST https://spinnaker.example.com/applications/my-app \
-H "Content-Type: application/json" \
-d '{
"name": "my-app",
"email": "team@example.com",
"description": "My sample application",
"cloudProviders": ["kubernetes"],
"instancePort": 80
}'
Defining a Pipeline
Pipelines are defined as JSON documents. The following example creates a pipeline that triggers on a Docker image push, deploys to a staging namespace, runs a manual judgment, and then deploys to production:
{
"name": "deploy-to-production",
"application": "my-app",
"stages": [
{
"name": "Deploy to Staging",
"type": "deployManifest",
"account": "my-k8s-account",
"namespace": "staging",
"manifests": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "my-app"
},
"spec": {
"replicas": 3,
"selector": {
"matchLabels": {
"app": "my-app"
}
},
"template": {
"metadata": {
"labels": {
"app": "my-app"
}
},
"spec": {
"containers": [
{
"name": "my-app",
"image": "registry.example.com/my-app:${trigger.artifact.version}",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}
]
},
{
"name": "Manual Judgment",
"type": "manualJudgment",
"instructions": "Review the staging deployment and approve for production.",
"judgmentInputs": []
},
{
"name": "Deploy to Production",
"type": "deployManifest",
"account": "my-k8s-account",
"namespace": "production",
"manifests": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "my-app"
},
"spec": {
"replicas": 5,
"selector": {
"matchLabels": {
"app": "my-app"
}
},
"template": {
"metadata": {
"labels": {
"app": "my-app"
}
},
"spec": {
"containers": [
{
"name": "my-app",
"image": "registry.example.com/my-app:${trigger.artifact.version}",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}
]
}
],
"triggers": [
{
"type": "docker",
"account": "my-docker-registry",
"repository": "registry.example.com/my-app"
}
]
}
Save this JSON to a file and create the pipeline via the API:
curl -X POST https://spinnaker.example.com/pipelines \
-H "Content-Type: application/json" \
-d @pipeline.json
Configuring CI Integration
Spinnaker integrates with CI systems to trigger pipelines based on build events. Jenkins is a common integration point.
Adding a Jenkins Master
hal config ci jenkins enable
hal config ci jenkins master add my-jenkins \
--address https://jenkins.example.com \
--username spinnaker \
--password YOUR_JENKINS_API_TOKEN
hal deploy apply
Once configured, you can add a Jenkins trigger to any pipeline:
{
"type": "jenkins",
"master": "my-jenkins",
"job": "my-app-build",
"propertyFile": "build.properties"
}
Implementing Deployment Strategies
Spinnaker supports several deployment strategies out of the box. The most common are blue/green and canary deployments.
Blue/Green Deployment
Blue/green deployments are configured using the red/black strategy in Spinnaker. This strategy deploys a new server group, waits for it to become healthy, and then disables the previous server group:
{
"name": "Blue/Green Deploy",
"type": "deploy",
"clusters": [
{
"account": "my-aws-account",
"application": "my-app",
"strategy": "redblack",
"stack": "production",
"freeFormDetails": "v${trigger.buildNumber}",
"capacity": {
"desired": 3,
"min": 3,
"max": 3
},
"loadBalancers": ["my-app-elb"],
"securityGroups": ["sg-12345678"],
"instanceType": "t3.medium"
}
]
}
Canary Deployment with Kayenta
Canary deployments gradually shift traffic to a new version while monitoring metrics. Kayenta performs automated canary analysis using signals from monitoring systems like Prometheus or Datadog.
First, configure Kayenta with a metrics provider:
hal config canary prometheus enable
hal config canary prometheus account add my-prometheus \
--base-url http://prometheus.example.com:9090
hal config canary edit \
--enabled true \
--default-metrics-account my-prometheus \
--default-storage-account my-s3-account
hal deploy apply
Then define a canary config that specifies the metrics to evaluate:
{
"name": "my-app-canary",
"description": "Canary analysis for my-app",
"metrics": [
{
"name": "request-latency",
"query": {
"type": "prometheus",
"customInlineTemplate": "avg(http_request_duration_seconds{app=\"my-app\"}) by (version)"
},
"analysisConfigurations": {
"canary": {
"direction": "DECREASE"
}
}
},
{
"name": "error-rate",
"query": {
"type": "prometheus",
"customInlineTemplate": "rate(http_requests_total{app=\"my-app\",status=~\"5..\"}[5m]) by (version)"
},
"analysisConfigurations": {
"canary": {
"direction": "DECREASE"
}
}
}
],
"scoreThresholds": {
"pass": 95,
"marginal": 75,
"fail": 75
}
}
Configuring Notifications
Spinnaker can send notifications through Slack, email, and other channels when pipeline events occur. To configure Slack notifications:
hal config notification slack edit \
--bot-name spinnaker-bot \
--token YOUR_SLACK_API_TOKEN
hal config notification slack enable
hal deploy apply
Add a notification stage to your pipeline:
{
"name": "Notify Slack",
"type": "slack",
"message": "Deployment of my-app completed successfully.",
"channel": "#deployments"
}
Best Practices
- Use version control for pipeline definitions: Store pipeline JSON files in Git so changes are tracked and reviewable through pull requests.
- Separate Spinnaker infrastructure from application clusters: Run Spinnaker in a dedicated cluster to avoid resource contention and improve reliability.
- Implement least-privilege access: Use Fiat RBAC to restrict who can create, modify, and execute pipelines. Grant write access only to deployment automation roles.
- Use immutable artifacts: Bake machine images or container images rather than configuring servers at runtime. This ensures consistency and simplifies rollbacks.
- Enable automated rollbacks: Configure pipeline stages to automatically roll back on failure, especially for production deployments.
- Monitor Spinnaker itself: Expose Spinnaker metrics to Prometheus or Datadog and set up alerts for service health, pipeline execution failures, and queue backlogs.
- Use deployment windows: Restrict production deployments to specific time windows to reduce risk during peak traffic periods.
- Test pipelines in a staging Spinnaker instance: Maintain a separate Spinnaker instance for testing pipeline changes before promoting them to production.
- Leverage templated pipelines: Use Spinnaker's pipeline templating feature (Dinghy or SpEL expressions) to reduce duplication across applications.
- Regularly upgrade Spinnaker: Keep up with the latest stable releases to benefit from security patches and new features. Always test upgrades in a staging environment first.
Backing Up and Restoring Configuration
Spinnaker configuration managed by Halyard is stored in ~/.hal. Regularly back up this directory:
tar -czf spinnaker-hal-backup-$(date +%Y%m%d).tar.gz ~/.hal
To restore, extract the archive and redeploy:
tar -xzf spinnaker-hal-backup-20240101.tar.gz -C ~/
hal deploy apply
For application and pipeline data stored in Front50, ensure your storage backend (S3, GCS) has versioning and lifecycle policies configured for disaster recovery.
Conclusion
Spinnaker is a powerful continuous delivery platform that enables teams to deploy applications reliably across multiple cloud environments. By understanding its architecture, properly configuring cloud providers, securing access with authentication and RBAC, and implementing progressive deployment strategies, organizations can achieve high deployment velocity without sacrificing stability. Following best practices such as version-controlling pipeline definitions, using immutable artifacts, and maintaining separate staging instances will help you get the most out of Spinnaker. While the initial setup requires careful planning, the long-term benefits of automated, auditable, and reversible deployments make Spinnaker an excellent choice for teams operating at scale.