Altinn / Altinn/altinn-platform

[POC] Create a portable Altinn Correspondence deployment for cloud-provider validation

Open
#3,909 0 comments 0 reactions 1 assignee Claimed by @ootneim View on GitHub
kind/portability
Dominant language
Go
Stars
13
Forks
7
Avg merge
19h 21m
Merged PRs (30d)
76

Description

## Background

As part of the Altinn cloud portability project, we need a lightweight Proof of Concept (POC) that cloud providers can deploy and test in their own environments.

The POC should use **Altinn Correspondence** as the representative Altinn component. Correspondence is containerised, has a relatively limited set of runtime dependencies, and already contains modular Azure infrastructure defined using Bicep.

The purpose is not to reproduce the complete Altinn platform. The POC should provide a realistic but simplified workload for evaluating:

- Deployment of Altinn components across different cloud platforms
- Mapping of Azure services to equivalent provider services
- Application and infrastructure portability
- Authentication and authorisation
- Workload identity and access to managed services
- Networking and observability
- Cloud-specific dependencies and potential vendor lock-in

## Goal

Create a documented and repeatable POC package that allows a cloud provider to deploy Altinn Correspondence and validate a representative authenticated API flow.

The same Correspondence container image should, as far as possible, be used across all providers. Provider-specific differences should primarily be handled through infrastructure, configuration and identity mapping.

## Current implementation

The current Correspondence infrastructure is implemented in Bicep under [`.azure`](https://github.com/Altinn/altinn-correspondence/tree/main/.azure).

The infrastructure currently includes modules for:

- Azure Container Apps and Container Apps Environment
- Azure Database for PostgreSQL
- Redis
- Azure Storage
- Azure Key Vault
- User-assigned managed identities and Azure RBAC
- Log Analytics
- Storage malware scanning and event integration
- Azure Policy and resource tagging
- GitHub Actions deployment using federated credentials

Relevant files:

- [`infrastructure/main.bicep`](https://github.com/Altinn/altinn-correspondence/blob/main/.azure/infrastructure/main.bicep)
- [`applications/api/main.bicep`](https://github.com/Altinn/altinn-correspondence/blob/main/.azure/applications/api/main.bicep)
- [`docker-compose.yml`](https://github.com/Altinn/altinn-correspondence/blob/main/docker-compose.yml)
- [`README-infrastructure.md`](https://github.com/Altinn/altinn-correspondence/blob/main/README-infrastructure.md)

The local Docker Compose environment uses PostgreSQL, Redis and Azurite. This should be evaluated as the starting point for defining the minimum runtime footprint.

Shared Azure API Management is maintained outside the Correspondence repository. It must therefore be treated as an external dependency or replaced with a lightweight ingress/API gateway in the POC.

## Proposed minimum POC scope

The initial POC should include:

- Correspondence API using the existing OCI container image
- PostgreSQL-compatible database
- Redis-compatible cache
- Object/blob storage for attachments
- Secret and configuration management
- Workload identity or equivalent service identity
- TLS-enabled ingress or API gateway
- Automated database migrations
- Minimal logging, metrics and health checks
- Automated deployment and teardown
- Repeatable authentication and API tests

External Altinn services should be configurable through endpoints.

Real Altinn test services should be used for authentication where practical. Non-essential integrations may be mocked or disabled to keep the POC lightweight.

## Authentication scenario

The POC must validate at least the following flow:

1. Obtain a Maskinporten token with the required Correspondence scopes.
2. Call a protected Correspondence endpoint.
3. Verify that a valid token is accepted.
4. Verify that missing, invalid or insufficiently scoped tokens are rejected.
5. Complete one representative Correspondence API happy path where dependencies and test data permit it.

Both authentication methods should be evaluated:

- Direct Maskinporten authentication
- Traditional Maskinporten-to-Altinn token exchange

See the [Correspondence authentication documentation](https://docs.altinn.studio/en/correspondence/getting-started/developer-guides/maskinporten/).

## Initial portability mapping

The following mapping must be validated and expanded during the POC:

| Current Azure implementation | Required capability | Portable POC approach |
|---|---|---|
| Azure Container Apps | Run an OCI container with scaling and ingress | Managed container service or managed Kubernetes |
| Azure Database for PostgreSQL | Relational database | Managed PostgreSQL-compatible service |
| Redis module | Distributed cache | Managed Redis-compatible service or containerised Redis |
| Azure Storage | Object/blob storage | Provider object storage or S3-compatible storage |
| Azure Key Vault | Secret and key management | Provider secret manager, External Secrets or Kubernetes Secrets |
| User-assigned managed identity | Workload identity | Provider workload identity or service account |
| Azure RBAC | Cloud-resource authorisation | Provider IAM roles and policies |
| Log Analytics | Central logging and diagnostics | Provider logging service and/or OpenTelemetry |
| Azure API Management | API gateway and ingress | Provider API gateway, load balancer or Kubernetes ingress |
| Defender for Storage and Event Grid | Attachment scanning and event handling | Provider-native solution or portable malware scanner |
| Azure Policy and tags | Governance and resource metadata | Provider policy framework and tagging |
| GitHub Actions with Azure OIDC | Federated CI/CD deployment | GitHub Actions with provider workload identity federation |
| GitHub Container Registry | OCI image distribution | Continue using GHCR or mirror to a provider registry |

For every mapping, document:

- Selected provider service
- Required configuration
- Functional differences
- Security implications
- Operational differences
- Estimated migration effort
- Portability risk
- Required application changes
- Known limitations or missing capabilities

## Tasks

### 1. Analyse the existing Correspondence deployment

- [ ] Review all Bicep files under `.azure/infrastructure`, `.azure/applications` and `.azure/modules`.
- [ ] Create an inventory of deployed Azure resources.
- [ ] Identify dependencies located outside the repository.
- [ ] Identify Azure-specific assumptions in the application and deployment workflows.
- [ ] Separate mandatory runtime dependencies from production-only capabilities.
- [ ] Document networking, DNS, firewall, identity and secret requirements.

### 2. Define the lightweight POC architecture

- [ ] Define the minimum components required to run Correspondence.
- [ ] Define which external Altinn services will be used and which can be mocked.
- [ ] Define the authentication scenarios.
- [ ] Define a cloud-neutral deployment contract for configuration, secrets, endpoints, ports and identities.
- [ ] Create an architecture diagram.
- [ ] Document which production capabilities are intentionally excluded.

### 3. Create the provider mapping

- [ ] Map each required Azure capability to a provider-neutral capability.
- [ ] Add provider-specific service mappings.
- [ ] Identify services without direct equivalents.
- [ ] Document required workarounds and application changes.
- [ ] Assign a portability rating and migration complexity to each component.
- [ ] Highlight vendor lock-in and security differences.

### 4. Build the POC deployment package

- [ ] Create reusable infrastructure code for the selected provider.
- [ ] Separate provider-specific implementations from the common deployment contract.
- [ ] Reuse the existing Correspondence container image without provider-specific rebuilding where possible.
- [ ] Add automated database migrations.
- [ ] Add deployment, validation and teardown workflows.
- [ ] Ensure secrets are not stored in source control.
- [ ] Provide example configuration containing only non-sensitive values.

Terraform modules combined with Helm, Kustomize or another portable workload definition should be considered.

The existing Bicep implementation should remain the source for understanding the current Azure architecture and required capabilities.

### 5. Validate the deployment

- [ ] Deploy the POC to at least one non-Azure cloud environment.
- [ ] Verify application health and database connectivity.
- [ ] Verify Redis and object-storage connectivity.
- [ ] Run the authenticated API test.
- [ ] Verify rejection of invalid and insufficiently scoped tokens.
- [ ] Verify logging, metrics and health endpoints.
- [ ] Record deployment time, required manual steps and estimated running cost.
- [ ] Document deviations from the current Azure implementation.

## Deliverables

- POC architecture and scope document
- Inventory of the current Correspondence Bicep infrastructure
- Azure-to-provider capability mapping
- Runnable provider-specific infrastructure code
- Deployment and teardown workflow
- Authentication and API validation scripts
- Cloud-provider test instructions
- Test report template
- Documented portability gaps and recommendations

## Acceptance criteria

- [ ] The current Correspondence Bicep implementation has been reviewed and documented.
- [ ] Mandatory and optional POC components are clearly separated.
- [ ] An Azure-to-provider mapping exists for every component included in the POC.
- [ ] The POC can be deployed using documented commands or an automated pipeline.
- [ ] No production data, credentials or secrets are required.
- [ ] The same Correspondence container image can be used across providers, or required changes are documented as portability gaps.
- [ ] Correspondence starts successfully and passes its health checks.
- [ ] PostgreSQL, Redis and object-storage integration have been validated.
- [ ] At least one authenticated Correspondence API flow has been completed.
- [ ] Invalid and insufficiently scoped authentication is rejected.
- [ ] At least one non-Azure deployment has been validated.
- [ ] Cloud-specific changes, limitations and workarounds are documented.
- [ ] The environment can be removed using the provided infrastructure workflow.
- [ ] Another cloud provider can follow the documentation without undocumented Altinn-specific knowledge.

## Out of scope

- Production traffic or production data
- Full production-scale high availability and disaster recovery
- Complete deployment of the Altinn platform
- Full parity with Altinn's shared API Management configuration
- Production SLA validation
- Complete performance and capacity testing
- Migration of existing Correspondence data
- Multi-region deployment

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.