diff --git a/.github/workflows/deploy-azure-aks.yml b/.github/workflows/deploy-azure-aks.yml index a7630e68..82215366 100644 --- a/.github/workflows/deploy-azure-aks.yml +++ b/.github/workflows/deploy-azure-aks.yml @@ -95,6 +95,9 @@ jobs: - tenant-service - enrollment-import-service - trading-partner-service + - premium-billing-service + - appeals-service + - rfai-service include: # Most .NET services need repo root as context to reach # src/services/shared/CloudHealthOffice.Infrastructure/ and/or src/engines/. @@ -125,6 +128,12 @@ jobs: build_context: '.' - service: reference-data-service build_context: '.' + - service: premium-billing-service + build_context: '.' + - service: appeals-service + build_context: '.' + - service: rfai-service + build_context: '.' steps: - uses: actions/checkout@v4 @@ -363,6 +372,19 @@ jobs: src/portal/CloudHealthOffice.Portal/k8s/portal-deployment.yaml \ | kubectl apply -f - + - name: Apply backend service manifests + run: | + ACR="${{ env.REGISTRY }}" + SHA="sha-${{ github.sha }}" + for manifest in src/services/*/k8s/*.yaml; do + echo "Applying ${manifest}..." + sed \ + -e "s|choacrhy6h2vdulfru6.azurecr.io/cloudhealthoffice-|${ACR}/cloudhealthoffice-|g" \ + -e "s|:latest|:${SHA}|g" \ + "$manifest" \ + | kubectl apply -f - + done + - name: Apply portal ingress (portal.cloudhealthoffice.com) run: kubectl apply -f infrastructure/k8s/portal-ingress.yaml diff --git a/scripts/deploy/deploy-core-services.sh b/scripts/deploy/deploy-core-services.sh index a613a77a..26d1ef11 100755 --- a/scripts/deploy/deploy-core-services.sh +++ b/scripts/deploy/deploy-core-services.sh @@ -52,6 +52,10 @@ SERVICES=( eligibility-service coverage-service enrollment-import-service + premium-billing-service + appeals-service + rfai-service + claims-scrubbing-service ) info() { echo "▸ $*"; } diff --git a/src/services/appeals-service/k8s/appeals-service-deployment.yaml b/src/services/appeals-service/k8s/appeals-service-deployment.yaml new file mode 100644 index 00000000..0fb01570 --- /dev/null +++ b/src/services/appeals-service/k8s/appeals-service-deployment.yaml @@ -0,0 +1,112 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: appeals-service-config + namespace: cloudhealthoffice +data: + ASPNETCORE_ENVIRONMENT: "Production" + CosmosDb__DatabaseName: "CloudHealthOffice" + AzureStorage__ContainerName: "appeal-attachments" + ClaimsService__BaseUrl: "http://claims-service.cloudhealthoffice" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: appeals-service + namespace: cloudhealthoffice + labels: + app: appeals-service + tier: backend +spec: + replicas: 1 + selector: + matchLabels: + app: appeals-service + template: + metadata: + labels: + app: appeals-service + tier: backend + spec: + containers: + - name: appeals-service + image: choacrhy6h2vdulfru6.azurecr.io/cloudhealthoffice-appeals-service:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + protocol: TCP + env: + - name: ASPNETCORE_ENVIRONMENT + valueFrom: + configMapKeyRef: + name: appeals-service-config + key: ASPNETCORE_ENVIRONMENT + - name: CosmosDb__AccountEndpoint + valueFrom: + secretKeyRef: + name: cosmos-db-secret + key: endpoint + - name: CosmosDb__AccountKey + valueFrom: + secretKeyRef: + name: cosmos-db-secret + key: key + - name: CosmosDb__DatabaseName + valueFrom: + configMapKeyRef: + name: appeals-service-config + key: CosmosDb__DatabaseName + - name: AzureStorage__ConnectionString + valueFrom: + secretKeyRef: + name: azure-storage-secret + key: connectionString + - name: AzureStorage__ContainerName + valueFrom: + configMapKeyRef: + name: appeals-service-config + key: AzureStorage__ContainerName + - name: ClaimsService__BaseUrl + valueFrom: + configMapKeyRef: + name: appeals-service-config + key: ClaimsService__BaseUrl + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + httpGet: + path: /health/live + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 +--- +apiVersion: v1 +kind: Service +metadata: + name: appeals-service + namespace: cloudhealthoffice + labels: + app: appeals-service +spec: + type: ClusterIP + selector: + app: appeals-service + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP diff --git a/src/services/claims-scrubbing-service/k8s/claims-scrubbing-service-deployment.yaml b/src/services/claims-scrubbing-service/k8s/claims-scrubbing-service-deployment.yaml new file mode 100644 index 00000000..d58f2573 --- /dev/null +++ b/src/services/claims-scrubbing-service/k8s/claims-scrubbing-service-deployment.yaml @@ -0,0 +1,122 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: claims-scrubbing-service-config + namespace: cloudhealthoffice +data: + NODE_ENV: "production" + KAFKA_BOOTSTRAP_SERVERS: "kafka.cloudhealthoffice:9092" + KAFKA_CLIENT_ID: "claims-scrubbing-service" + KAFKA_CONSUMER_GROUP: "claims-scrubbers" + INBOUND_CLAIMS_TOPIC: "claims.inbound" + CLEAN_CLAIMS_TOPIC: "claims.clean" + FLAGGED_CLAIMS_TOPIC: "claims.flagged" + REJECTED_CLAIMS_TOPIC: "claims.rejected" + COSMOS_DATABASE: "CloudHealthOffice" + COSMOS_RULES_CONTAINER: "ScrubRules" + COSMOS_AUDIT_CONTAINER: "ScrubAudit" + CLAIMS_CONTAINER: "claims-archive" + PARALLEL_RULES: "true" + MAX_RULE_CONCURRENCY: "10" + RULE_TIMEOUT_MS: "5000" + CACHE_RULES: "true" + RULE_CACHE_TTL: "300" + MAX_ERRORS_FOR_REJECTION: "3" + MAX_WARNINGS_FOR_FLAGGING: "5" + ENABLE_DUPLICATE_DETECTION: "true" + ENABLE_MEDICAL_NECESSITY: "true" + ENABLE_NCCI_EDITS: "true" + ENABLE_AUTO_CORRECTION: "false" + ENABLE_REALTIME_NPI: "false" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: claims-scrubbing-service + namespace: cloudhealthoffice + labels: + app: claims-scrubbing-service + tier: backend +spec: + replicas: 1 + selector: + matchLabels: + app: claims-scrubbing-service + template: + metadata: + labels: + app: claims-scrubbing-service + tier: backend + spec: + containers: + - name: claims-scrubbing-service + image: choacrhy6h2vdulfru6.azurecr.io/cloudhealthoffice-claims-scrubbing-service:latest + imagePullPolicy: Always + ports: + - containerPort: 3000 + name: http + protocol: TCP + envFrom: + - configMapRef: + name: claims-scrubbing-service-config + env: + - name: KAFKA_SASL_USERNAME + valueFrom: + secretKeyRef: + name: kafka-secret + key: saslUsername + optional: true + - name: KAFKA_SASL_PASSWORD + valueFrom: + secretKeyRef: + name: kafka-secret + key: saslPassword + optional: true + - name: COSMOS_ENDPOINT + valueFrom: + secretKeyRef: + name: cosmos-db-secret + key: endpoint + - name: STORAGE_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: azure-storage-secret + key: connectionString + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + httpGet: + path: /livez + port: 3000 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /readyz + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 +--- +apiVersion: v1 +kind: Service +metadata: + name: claims-scrubbing-service + namespace: cloudhealthoffice + labels: + app: claims-scrubbing-service +spec: + type: ClusterIP + selector: + app: claims-scrubbing-service + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP diff --git a/src/services/premium-billing-service/k8s/premium-billing-service-deployment.yaml b/src/services/premium-billing-service/k8s/premium-billing-service-deployment.yaml new file mode 100644 index 00000000..7661e6f5 --- /dev/null +++ b/src/services/premium-billing-service/k8s/premium-billing-service-deployment.yaml @@ -0,0 +1,124 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: premium-billing-service-config + namespace: cloudhealthoffice +data: + ASPNETCORE_ENVIRONMENT: "Production" + CosmosDb__DatabaseName: "CloudHealthOffice" + CoverageService__BaseUrl: "http://coverage-service.cloudhealthoffice" + SponsorService__BaseUrl: "http://sponsor-service.cloudhealthoffice" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: premium-billing-service + namespace: cloudhealthoffice + labels: + app: premium-billing-service + tier: backend +spec: + replicas: 1 + selector: + matchLabels: + app: premium-billing-service + template: + metadata: + labels: + app: premium-billing-service + tier: backend + spec: + containers: + - name: premium-billing-service + image: choacrhy6h2vdulfru6.azurecr.io/cloudhealthoffice-premium-billing-service:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + protocol: TCP + env: + - name: ASPNETCORE_ENVIRONMENT + valueFrom: + configMapKeyRef: + name: premium-billing-service-config + key: ASPNETCORE_ENVIRONMENT + - name: MongoDb__ConnectionString + valueFrom: + secretKeyRef: + name: mongodb-secret + key: connectionString + optional: true + - name: CosmosDb__Endpoint + valueFrom: + secretKeyRef: + name: cosmos-db-secret + key: endpoint + - name: CosmosDb__Key + valueFrom: + secretKeyRef: + name: cosmos-db-secret + key: key + - name: CosmosDb__DatabaseName + valueFrom: + configMapKeyRef: + name: premium-billing-service-config + key: CosmosDb__DatabaseName + - name: CoverageService__BaseUrl + valueFrom: + configMapKeyRef: + name: premium-billing-service-config + key: CoverageService__BaseUrl + - name: SponsorService__BaseUrl + valueFrom: + configMapKeyRef: + name: premium-billing-service-config + key: SponsorService__BaseUrl + - name: Stripe__SecretKey + valueFrom: + secretKeyRef: + name: stripe-api-keys + key: secret-key + - name: Stripe__WebhookSecret + valueFrom: + secretKeyRef: + name: stripe-api-keys + key: webhook-secret + optional: true + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + httpGet: + path: /health/live + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 +--- +apiVersion: v1 +kind: Service +metadata: + name: premium-billing-service + namespace: cloudhealthoffice + labels: + app: premium-billing-service +spec: + type: ClusterIP + selector: + app: premium-billing-service + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP diff --git a/src/services/rfai-service/k8s/rfai-service-deployment.yaml b/src/services/rfai-service/k8s/rfai-service-deployment.yaml new file mode 100644 index 00000000..adaefbd6 --- /dev/null +++ b/src/services/rfai-service/k8s/rfai-service-deployment.yaml @@ -0,0 +1,107 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: rfai-service-config + namespace: cloudhealthoffice +data: + ASPNETCORE_ENVIRONMENT: "Production" + CosmosDb__DatabaseName: "CloudHealthOffice" + CosmosDb__RfaiContainer: "RfaiCases" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: rfai-service + namespace: cloudhealthoffice + labels: + app: rfai-service + tier: backend +spec: + replicas: 1 + selector: + matchLabels: + app: rfai-service + template: + metadata: + labels: + app: rfai-service + tier: backend + spec: + containers: + - name: rfai-service + image: choacrhy6h2vdulfru6.azurecr.io/cloudhealthoffice-rfai-service:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + protocol: TCP + env: + - name: ASPNETCORE_ENVIRONMENT + valueFrom: + configMapKeyRef: + name: rfai-service-config + key: ASPNETCORE_ENVIRONMENT + - name: MongoDb__ConnectionString + valueFrom: + secretKeyRef: + name: mongodb-secret + key: connectionString + optional: true + - name: CosmosDb__Endpoint + valueFrom: + secretKeyRef: + name: cosmos-db-secret + key: endpoint + - name: CosmosDb__Key + valueFrom: + secretKeyRef: + name: cosmos-db-secret + key: key + - name: CosmosDb__DatabaseName + valueFrom: + configMapKeyRef: + name: rfai-service-config + key: CosmosDb__DatabaseName + - name: CosmosDb__RfaiContainer + valueFrom: + configMapKeyRef: + name: rfai-service-config + key: CosmosDb__RfaiContainer + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + httpGet: + path: /health/live + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 +--- +apiVersion: v1 +kind: Service +metadata: + name: rfai-service + namespace: cloudhealthoffice + labels: + app: rfai-service +spec: + type: ClusterIP + selector: + app: rfai-service + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP