Skip to content

Commit 2bfdbd3

Browse files
committed
Merge branch 'main' into test-driver-did-andorra
2 parents 7027b94 + 4a304cb commit 2bfdbd3

27 files changed

Lines changed: 2142 additions & 638 deletions

.github/workflows/kubernetes-deploy-to-cluster.yml

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,42 @@ on:
44
workflow_dispatch:
55

66
jobs:
7-
build:
7+
deploy:
88
runs-on: ubuntu-latest
99
steps:
10-
- uses: actions/checkout@master
10+
- name: Checkout repository
11+
uses: actions/checkout@v4
1112

1213
- name: Import Secrets
13-
uses: hashicorp/vault-action@v2.3.0
14+
uses: hashicorp/vault-action@v3
1415
with:
1516
url: ${{ secrets.VAULT_ADDR }}
1617
token: ${{ secrets.CI_SECRET_READER_PERIODIC_TOKEN }}
1718
caCertificate: ${{ secrets.VAULTCA }}
1819
secrets: |
19-
ci/data/gh-workflows/universal-resolver-cluster dif-cluster-kube-config | KUBE_CONFIG_DATA ;
2020
ci/data/gh-workflows/universal-resolver-cluster aws-access-key-id | AWS_ACCESS_KEY_ID ;
2121
ci/data/gh-workflows/universal-resolver-cluster aws-secret-access-key | AWS_SECRET_ACCESS_KEY ;
2222
ci/data/gh-workflows/universal-resolver-cluster rpc-url-testnet | RPC_URL_TESTNET ;
23-
ci/data/gh-workflows/universal-resolver-cluster rpc-cert-testnet | RPC_CERT_TESTNET ;
24-
ci/data/gh-workflows/deployment-status slack-webhook-url | SLACK_WEBHOOK_URL
23+
ci/data/gh-workflows/universal-resolver-cluster rpc-cert-testnet | RPC_CERT_TESTNET
2524
26-
- name: Deploy to AWS
25+
- name: Deploy to AWS Kubernetes Cluster
2726
uses: ./ci/deploy-k8s-aws
28-
env:
29-
KUBE_CONFIG_DATA: ${{secrets.KUBE_CONFIG_DATA_BASE64_UNI_RESOLVER_PROD}}
30-
AWS_ACCESS_KEY_ID: ${{env.AWS_ACCESS_KEY_ID}}
31-
AWS_SECRET_ACCESS_KEY: ${{env.AWS_SECRET_ACCESS_KEY}}
32-
RPC_URL_TESTNET: ${{env.RPC_URL_TESTNET}}
33-
RPC_CERT_TESTNET: ${{env.RPC_CERT_TESTNET}}
27+
with:
28+
kube-config-data: ${{ secrets.KUBE_CONFIG_DATA_BASE64_UNI_RESOLVER_PROD }}
29+
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
30+
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
31+
rpc-url-testnet: ${{ env.RPC_URL_TESTNET }}
32+
rpc-cert-testnet: ${{ env.RPC_CERT_TESTNET }}
33+
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
34+
github-server-url: ${{ github.server_url }}
35+
github-repository: ${{ github.repository }}
36+
github-run-id: ${{ github.run_id }}
3437

3538
- name: Slack notification
36-
if: failure() # Send message only on failure
39+
if: failure()
3740
uses: 8398a7/action-slack@v3
3841
with:
3942
status: ${{ job.status }}
40-
fields: repo,commit,action,eventName,ref,workflow # selectable (default: repo,message)
43+
fields: repo,commit,action,eventName,ref,workflow
4144
env:
42-
SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }} # required
45+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

.github/workflows/nightly-did-lint-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ jobs:
1919
status: ${{ job.status }}
2020
fields: repo,commit,action,eventName,ref,workflow
2121
env:
22-
SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }}
22+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
2323
if: failure()

.github/workflows/nightly-did-test-suite.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
- uses: actions/checkout@master
11-
- name: Import Secrets
12-
uses: hashicorp/vault-action@v2.3.0
13-
with:
14-
url: ${{ secrets.VAULT_ADDR }}
15-
token: ${{ secrets.CI_SECRET_READER_PERIODIC_TOKEN }}
16-
caCertificate: ${{ secrets.VAULTCA }}
17-
secrets: |
18-
ci/data/gh-workflows/deployment-status slack-webhook-url | SLACK_WEBHOOK_URL
1911
- name: Get driver status
2012
uses: ./ci/get-driver-status
2113
with:
@@ -34,5 +26,5 @@ jobs:
3426
status: ${{ job.status }}
3527
fields: repo,commit,action,eventName,ref,workflow
3628
env:
37-
SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }}
29+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3830
if: failure()

README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,9 @@ You should then be able to resolve identifiers locally using simple `curl` reque
9797
curl -X GET 'http://localhost:8080/1.0/identifiers/did:iden3:polygon:amoy:xC8VZLUUfo5p9DWUawReh7QSstmYN6zR7qsQhQCsw?gist=f12d4f6fddeed78cb8b1faf1c6f4f171a590c1b05c484118a09847f5caa74d03'
9898
curl -X GET 'http://localhost:8080/1.0/identifiers/did:iden3:polygon:amoy:xC8VZLUUfo5p9DWUawReh7QSstmYN6zR7qsQhQCsw?state=7a1a45d22b686cf1bd2f9fbecbed38b725a555e6d8ad68d3780feda9124b1a13'
9999
curl -X GET http://localhost:8080/1.0/identifiers/did:cndid:sf24eYrmwXt6nx4fig3XJm7n9UP6PNRJ3
100-
curl -X GET http://localhost:8080/1.0/identifiers/did:btcr2:k1qypcylxwhf8sykn2dztm6z8lxm43kwkyzf07qmp9jafv3zfntmpwtks9hmnrw
101-
100+
curl -X GET http://localhost:8080/1.0/identifiers/did:btcr2:k1q5ppmnfjqp0qe5klmnll9tazz9jd5ds43x5xfsr3hu9jdgaldu0d3jgs0vj4r
102101
curl -X GET http://localhost:8080/1.0/identifiers/did:tgrid:trustgrid:dev:QjA1qdXKmxzgK4u8mFoBpF
103-
104102
curl -X GET http://localhost:8080/1.0/identifiers/did:near:CF5RiJYh4EVmEt8UADTjoP3XaZo1NPWxv6w5TmkLqjpR
105-
106103
curl -X GET http://localhost:8080/1.0/identifiers/did:empe:testnet:006308981b61932c5eaae1c39ace8ee3892f4a1f
107104

108105

@@ -186,7 +183,6 @@ Are you developing a DID method and Universal Resolver driver? Click [Driver Dev
186183
| [did-evrc](https://github.com/vcian/uni-resolver-driver-did-evrc) | 1.0 | 1.0 | [viitorcloud/uni-resolver-driver-did-evrc](https://hub.docker.com/r/viitorcloud/uni-resolver-driver-did-evrc) | EveryCRED DID Method |
187184
| [did-keri](https://github.com/hyperledger-labs/did-webs-resolver) | 0.1 | [0.1](https://trustoverip.github.io/tswg-did-method-webs-specification/) | [gleif/did-keri-resolver](https://hub.docker.com/r/gleif/did-keri-resolver) | KERI |
188185
| [did-webs](https://github.com/hyperledger-labs/did-webs-resolver) | 0.2.1 | [0.1](https://trustoverip.github.io/tswg-did-method-webs-specification/) | [gleif/did-webs-resolver](https://hub.docker.com/r/gleif/did-webs-resolver) | KERI, Web |
189-
| [did-content](https://github.com/KataruInc/did-content-spec) | 0.1 | [0.1](https://github.com/KataruInc/did-content-spec) | [kataru/content-did-driver](https://hub.docker.com/repository/docker/kataru/content-did-driver) | Content DID |
190186
| [did-algo](https://github.com/algorandfoundation/did-algo) | 1.0.0 | [2.0](https://github.com/algorandfoundation/did-algo/blob/main/SPEC.md) | [ghcr.io/algorandfoundation/did-algo](https://ghcr.io/algorandfoundation/did-algo) | Algorand Blockchain DID Method |
191187
| [did-itn](https://github.com/itn-trust/uni-resolver-driver-did-itn) | 1.0.0 | [1.0](https://github.com/itn-trust/itn-did-spec) | [ghcr.io/itn-trust/driver-did-itn](https://ghcr.io/itn-trust/driver-did-itn) | Integrated Trust Network (ITN) DID Method |
192188
| [did-iota](https://github.com/iotaledger/uni-resolver-driver-iota) | 0.2 | 2.0 | [iotaledger/uni-resolver-driver-iota](https://hub.docker.com/r/iotaledger/uni-resolver-driver-iota) | IOTA DID |

ci/deploy-k8s-aws/Dockerfile

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
1-
FROM python:3.8-slim
1+
FROM debian:bookworm-slim
22

33
LABEL "name"="Deployment of the Universal Resolver to a Kubernetes Cluster"
44
LABEL "maintainer"="Bernhard Fuchs <bernhard.fuchs@danubetech.com>"
5-
LABEL "version"="1.0.0"
5+
LABEL "version"="2.0.0"
66

77
LABEL "com.github.actions.name"="GitHub Action for deploying the Universal Resolver"
8-
LABEL "com.github.actions.description"="Deployes the Universal Resolver to a Kubernetes cluster."
8+
LABEL "com.github.actions.description"="Deploys the Universal Resolver to a Kubernetes cluster with smart deployment strategy."
99
LABEL "com.github.actions.icon"="package"
1010
LABEL "com.github.actions.color"="blue"
1111

12+
# Install base tools and AWS CLI
1213
RUN apt-get update -y && \
13-
apt-get install -y curl gnupg openssh-client git && \
14-
curl -Lso /bin/aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.11.5/2018-12-06/bin/linux/amd64/aws-iam-authenticator && \
14+
apt-get install -y curl gnupg openssh-client git unzip jq ca-certificates && \
15+
# Install AWS CLI v2
16+
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
17+
unzip awscliv2.zip && \
18+
./aws/install && \
19+
rm -rf awscliv2.zip aws && \
20+
# Install AWS IAM Authenticator (latest version compatible with EKS 1.33)
21+
curl -Lso /bin/aws-iam-authenticator https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v0.6.30/aws-iam-authenticator_0.6.30_linux_amd64 && \
1522
chmod +x /bin/aws-iam-authenticator && \
16-
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.6/bin/linux/amd64/kubectl && \
17-
chmod +x ./kubectl && \
18-
mv ./kubectl /usr/local/bin/kubectl && \
23+
# Note: kubectl will be installed dynamically in entrypoint.sh to match EKS cluster version
24+
# Install yq for YAML parsing
25+
curl -Lso /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 && \
26+
chmod +x /usr/local/bin/yq && \
27+
# Cleanup
1928
apt-get -y clean && apt-get -y autoclean && apt-get -y autoremove && \
20-
pip install setuptools awscli
29+
rm -rf /var/lib/apt/lists/*
2130

22-
COPY app-specs /app-specs
23-
COPY namespace /namespace
24-
COPY scripts /
25-
RUN chmod +x /entrypoint.sh
26-
ENTRYPOINT ["/entrypoint.sh"]
31+
# Copy deployment scripts
32+
COPY scripts /scripts
33+
RUN chmod +x /scripts/*.sh
34+
35+
ENTRYPOINT ["/scripts/entrypoint.sh"]

ci/deploy-k8s-aws/README.md

Lines changed: 170 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,186 @@
11
# Kubernetes Deployment of the Universal Resolver
22

3-
## Usage with Docker
4-
Setting the environment:
3+
## Overview
54

6-
export KUBE_CONFIG_DATA=$(cat /home/pp/dev/devops/universal-resolver-kubernetes/aws/danubetech-dev-cluster10/danubetech-dev-cluster10-KUBE_CONFIG_DATA.txt)
5+
This GitHub Action deploys the Universal Resolver to a Kubernetes cluster using a smart deployment strategy that minimizes downtime and only updates services when their container images have changed.
76

8-
Build:
7+
**Version:** 2.0.0
98

10-
docker build -t ur-deployer .
9+
## Features
1110

12-
Run:
11+
- **Smart Deployment**: Only updates deployments when container images differ from the running version
12+
- **Zero Downtime**: Unchanged services continue running without interruption
13+
- **Automatic Cleanup**: Removes orphaned deployments not defined in docker-compose.yml
14+
- **ConfigMap Management**: Automatically creates ConfigMaps from .env file
15+
- **Health Verification**: Verifies all deployments are healthy before completing
16+
- **Special Case Handling**: Manages secrets for driver-did-btcr
1317

14-
docker run -t ur-deployer
18+
## Architecture
1519

20+
The action is composed of modular bash scripts that handle different aspects of deployment:
1621

17-
## Usage via script
18-
Setting the environment:
22+
1. **parse-compose.sh** - Parses docker-compose.yml and extracts service definitions
23+
2. **process-env.sh** - Creates ConfigMaps from .env file
24+
3. **deploy-services.sh** - Implements smart deployment logic
25+
4. **handle-btcr-secret.sh** - Handles driver-did-btcr secret configuration
26+
5. **cleanup-orphaned.sh** - Removes orphaned resources
27+
6. **verify-deployment.sh** - Verifies deployment health
28+
7. **entrypoint.sh** - Orchestrates all scripts
1929

20-
export KUBECONFIG=/home/pp/dev/devops/universal-resolver-kubernetes/aws/danubetech-dev-cluster10/kubeconfig-danubetech-dev-cluster10.yaml
30+
## Usage in GitHub Actions
2131

22-
Run:
23-
24-
cd scripts
25-
./entrypoint.sh
32+
```yaml
33+
- name: Deploy to AWS Kubernetes Cluster
34+
uses: ./ci/deploy-k8s-aws
35+
with:
36+
kube-config-data: ${{ secrets.KUBE_CONFIG_DATA }}
37+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
38+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
39+
namespace: 'uni-resolver'
40+
rpc-url-testnet: ${{ secrets.RPC_URL_TESTNET }}
41+
rpc-cert-testnet: ${{ secrets.RPC_CERT_TESTNET }}
42+
```
2643
44+
## Inputs
45+
46+
| Input | Description | Required | Default |
47+
|-------|-------------|----------|---------|
48+
| `kube-config-data` | Base64-encoded Kubernetes configuration | Yes | - |
49+
| `aws-access-key-id` | AWS Access Key ID | Yes | - |
50+
| `aws-secret-access-key` | AWS Secret Access Key | Yes | - |
51+
| `namespace` | Kubernetes namespace | No | `uni-resolver` |
52+
| `rpc-url-testnet` | RPC URL for driver-did-btcr | No | - |
53+
| `rpc-cert-testnet` | RPC certificate for driver-did-btcr | No | - |
54+
55+
## How It Works
56+
57+
### 1. Parse docker-compose.yml
58+
The action reads your docker-compose.yml file (the source of truth) and extracts all service definitions including:
59+
- Container images and tags
60+
- Port mappings
61+
- Environment variables
62+
- Volume mounts
63+
64+
### 2. Smart Deployment Logic
65+
For each service in docker-compose.yml:
66+
- **If deployment exists**: Compare current image with desired image
67+
- If different: Update deployment and wait for rollout
68+
- If same: Skip (no downtime)
69+
- **If deployment doesn't exist**: Create new deployment and service
70+
71+
### 3. Automatic Cleanup
72+
After deploying all services:
73+
- Identify deployments with `managed-by=github-action` label
74+
- Compare with services in docker-compose.yml
75+
- Remove any orphaned resources (deployments, services, configmaps)
76+
77+
### 4. Health Verification
78+
Verify that all deployments are healthy:
79+
- Check ready replicas match desired replicas
80+
- Display pod status and recent events
81+
- Exit with error if any deployment is unhealthy
82+
83+
## Benefits Over Previous Approach
84+
85+
### Previous (Destructive)
86+
- Deleted entire namespace on every deployment
87+
- All services restarted, causing downtime
88+
- No version checking
89+
- Inefficient for versioned containers
90+
91+
### Current (Smart)
92+
- Only updates changed services
93+
- Zero downtime for unchanged services
94+
- Faster deployments
95+
- Maintains persistent state
96+
- Better observability
97+
98+
## Local Development
99+
100+
### Build Docker Image
101+
```bash
102+
cd ci/deploy-k8s-aws
103+
docker build -t ur-deployer .
104+
```
27105

28-
## Usage as GitHub Action
106+
### Run Locally
107+
```bash
108+
docker run -t \
109+
-e KUBE_CONFIG_DATA="$(cat ~/.kube/config | base64)" \
110+
-e AWS_ACCESS_KEY_ID="your-key" \
111+
-e AWS_SECRET_ACCESS_KEY="your-secret" \
112+
-e NAMESPACE="uni-resolver" \
113+
-v $(pwd)/../..:/workspace \
114+
-w /workspace \
115+
ur-deployer
116+
```
29117

30-
Github Action workflow-file:
118+
## Directory Structure
31119

32120
```
33-
name: CI/CD Workflow for universal-resolver
34-
35-
on:
36-
push:
37-
branches:
38-
- master
39-
pull_request:
40-
branches:
41-
- master
42-
43-
jobs:
44-
build:
45-
runs-on: ubuntu-latest
46-
steps:
47-
- uses: actions/checkout@master
48-
- name: Deploy to AWS
49-
uses: philpotisk/universal-resolver-k8s-deployment@master
50-
env:
51-
KUBE_CONFIG_DATA: ${{secrets.KUBE_CONFIG_DATA}}
52-
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
53-
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
54-
```
121+
ci/deploy-k8s-aws/
122+
├── action.yml # GitHub Action definition
123+
├── Dockerfile # Container image with tools
124+
├── README.md # This file
125+
└── scripts/
126+
├── entrypoint.sh # Main orchestration script
127+
├── parse-compose.sh # Parse docker-compose.yml
128+
├── process-env.sh # Create ConfigMaps
129+
├── deploy-services.sh # Smart deployment logic
130+
├── handle-btcr-secret.sh # Special case handling
131+
├── cleanup-orphaned.sh # Remove orphaned resources
132+
└── verify-deployment.sh # Health verification
133+
```
134+
135+
## Requirements
136+
137+
### Container Image Includes
138+
- AWS CLI v2
139+
- AWS IAM Authenticator
140+
- kubectl (latest stable)
141+
- yq (YAML processor)
142+
- jq (JSON processor)
143+
144+
### Source of Truth
145+
- **docker-compose.yml** - All services must be defined here
146+
- **.env** - Environment variables (optional)
147+
148+
## Troubleshooting
149+
150+
### Deployment Fails
151+
Check the logs for each step. The action provides detailed output for:
152+
- Parsing errors
153+
- Connection issues
154+
- Deployment failures
155+
- Health check failures
156+
157+
### Service Not Updating
158+
Ensure the image tag in docker-compose.yml is different from the deployed version.
159+
160+
### Orphaned Resources Not Cleaned
161+
Only resources with the `managed-by=github-action` label are cleaned up. Manually created resources are not affected.
162+
163+
## Migration from Previous Version
164+
165+
The previous version used Python scripts and a destructive deployment strategy. This version:
166+
1. Uses bash scripts for better maintainability
167+
2. Implements smart deployment logic
168+
3. Eliminates unnecessary downtime
169+
4. Removes dependency on manually maintained deployment specs
170+
171+
All services must now be defined in docker-compose.yml. The app-specs and namespace folders are no longer used.
172+
173+
## Version History
174+
175+
### 2.0.0 (Current)
176+
- Complete refactor to bash-based approach
177+
- Smart deployment strategy
178+
- Automatic cleanup of orphaned resources
179+
- ConfigMap management from .env
180+
- Improved health verification
181+
- Zero downtime for unchanged services
182+
183+
### 1.0.0 (Legacy)
184+
- Python-based scripts
185+
- Destructive deployment (delete namespace)
186+
- Manual deployment spec maintenance

0 commit comments

Comments
 (0)