diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 092c931a..65a90fa9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,6 +35,7 @@ jobs: - name: demo runOnPullRequest: true app: demo + env: default path: ./samples/demo/app.bicep args: --application demo uiTestFile: tests/demo/demo.app.spec.ts @@ -44,33 +45,36 @@ jobs: - name: dapr runOnPullRequest: true app: dapr + env: default path: ./samples/dapr/dapr.bicep enableDapr: true - name: volumes runOnPullRequest: true app: myapp + env: default path: ./samples/volumes/app.bicep enableDapr: false - - name: eshop + - name: eshop-containers runOnPullRequest: true app: eshop - path: ./samples/eshop/iac/eshop.bicep - uiTestFile: tests/eshop/container.app.spec.ts + env: default + path: ./samples/eshop/eshop.bicep + uiTestFile: tests/eshop/eshop.app.spec.ts enableDapr: false - name: eshop-azure runOnPullRequest: false - app: eshop-azure - path: ./samples/eshop/iac/eshop.bicep - args: -p platform=azure -p appName=eshop-azure - uiTestFile: tests/eshop/container.app.spec.ts + app: eshop + env: azure + path: ./samples/eshop/eshop.bicep + uiTestFile: tests/eshop/eshop.app.spec.ts credential: azure enableDapr: false - name: eshop-aws runOnPullRequest: false - app: eshop-aws-${{ github.run_id }}-${{ github.run_attempt }} - path: ./samples/eshop/iac/eshop.bicep - args: -p platform=aws -p eksClusterName=eks-samplestest-${{ github.run_id }}-${{ github.run_attempt }}-eshop-aws -p appName=eshop-aws-${{ github.run_id }}-${{ github.run_attempt }} - uiTestFile: tests/eshop/container.app.spec.ts + app: eshop + env: aws + path: ./samples/eshop/eshop.bicep + uiTestFile: tests/eshop/eshop.app.spec.ts credential: aws enableDapr: false env: @@ -161,12 +165,9 @@ jobs: echo "Waiting for EKS cluster to be created..." sleep 60 done + aws eks update-kubeconfig --region ${{ env.AWS_REGION }} --name ${{ steps.gen-id.outputs.TEST_EKS_CLUSTER_NAME }} timeout-minutes: 60 continue-on-error: false - - name: Install k3d - if: steps.gen-id.outputs.RUN_TEST == 'true' && matrix.credential == 'aws' - run: | - aws eks update-kubeconfig --region ${{ env.AWS_REGION }} --name ${{ steps.gen-id.outputs.TEST_EKS_CLUSTER_NAME }} - name: Download k3d if: steps.gen-id.outputs.RUN_TEST == 'true' && matrix.credential != 'aws' run: wget -q -O - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash @@ -186,7 +187,7 @@ jobs: RADIUS_VERSION=edge fi ./.github/scripts/install-radius.sh $RADIUS_VERSION - - name: Initialize local environment + - name: Initialize default environment if: steps.gen-id.outputs.RUN_TEST == 'true' run: | if [[ "${{ matrix.credential }}" == "aws" ]]; then @@ -201,6 +202,11 @@ jobs: rad env switch default rad recipe register default -e default -w default --template-kind bicep --template-path ghcr.io/radius-project/recipes/local-dev/rediscaches:latest --resource-type Applications.Datastores/redisCaches rad recipe register default -e default -w default --template-kind bicep --template-path ghcr.io/radius-project/recipes/local-dev/mongodatabases:latest --resource-type Applications.Datastores/mongoDatabases + rad recipe register default -e default -w default --template-kind bicep --template-path ghcr.io/radius-project/recipes/local-dev/sqldatabases:latest --resource-type Applications.Datastores/sqlDatabases + rad recipe register default -e default -w default --template-kind bicep --template-path ghcr.io/radius-project/recipes/local-dev/rabbitmqqueues:latest --resource-type Applications.Messaging/rabbitMQQueues + - name: Configure cloud credentials + if: steps.gen-id.outputs.RUN_TEST == 'true' && ( matrix.credential == 'azure' || matrix.credential == 'aws') + run: | if [[ "${{ matrix.credential }}" == "azure" ]]; then rad env update default --azure-subscription-id ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} --azure-resource-group ${{ steps.gen-id.outputs.TEST_AZURE_RESOURCE_GROUP }} rad credential register azure --client-id ${{ secrets.AZURE_SP_TESTS_APPID }} --client-secret ${{ secrets.AZURE_SP_TESTS_PASSWORD }} --tenant-id ${{ secrets.AZURE_SP_TESTS_TENANTID }} @@ -209,6 +215,16 @@ jobs: rad env update default --aws-region ${{ env.AWS_REGION }} --aws-account-id ${{ secrets.AWS_ACCOUNT_ID }} rad credential register aws --access-key-id ${{ secrets.AWS_ACCESS_KEY_ID }} --secret-access-key ${{ secrets.AWS_SECRET_ACCESS_KEY }} fi + ## This step is temporary until we have Recipe Packs for Azure & AWS and update the eShop sample + - name: Initialize eShop environments + if: steps.gen-id.outputs.RUN_TEST == 'true' && matrix.app == 'eshop' + run: | + if [[ "${{ matrix.credential }}" == "azure" ]]; then + rad deploy ./samples/eshop/environments/azure.bicep -p azureResourceGroup=${{ steps.gen-id.outputs.TEST_AZURE_RESOURCE_GROUP }} -p azureSubscriptionId=${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} + elif [[ "${{ matrix.credential }}" == "aws" ]]; then + rad deploy ./samples/eshop/environments/aws.bicep -p awsAccountId=${{ secrets.AWS_ACCOUNT_ID }} -p awsRegion=${{ env.AWS_REGION }} -p eksClusterName=${{ steps.gen-id.outputs.TEST_EKS_CLUSTER_NAME }} + fi + rad env switch ${{ matrix.env }} # Deploy application and run tests - name: Deploy app if: steps.gen-id.outputs.RUN_TEST == 'true' @@ -217,7 +233,7 @@ jobs: if: steps.gen-id.outputs.RUN_TEST == 'true' id: wait-for-pods run: | - namespace="default-${{ matrix.app }}" + namespace="${{ matrix.env }}-${{ matrix.app }}" label="radapp.io/application=${{ matrix.app }}" kubectl wait --for=condition=Ready pod -l $label -n $namespace --timeout=5m - name: Run Playwright Test @@ -275,7 +291,7 @@ jobs: - name: Delete app if: steps.gen-id.outputs.RUN_TEST == 'true' run: | - rad app delete ${{ matrix.app }} -y + rad app delete ${{ matrix.app }} -y - name: Delete Azure resource group if: always() && steps.gen-id.outputs.RUN_TEST == 'true' && steps.create-azure-resource-group.outcome == 'success' run: | diff --git a/playwright/tests/eshop/container.app.spec.ts b/playwright/tests/eshop/eshop.app.spec.ts similarity index 100% rename from playwright/tests/eshop/container.app.spec.ts rename to playwright/tests/eshop/eshop.app.spec.ts diff --git a/samples/eshop/README.md b/samples/eshop/README.md index a8869007..42cb4521 100644 --- a/samples/eshop/README.md +++ b/samples/eshop/README.md @@ -1,7 +1,5 @@ # eShop on Radius reference application -Visit the [Project Radius docs](https://docs.radapp.io/tutorials/eshop/) to learn more and try it out. - ## Source This reference app is a "radified" version of the [eShop on containers](https://github.com/dotnet-architecture/eShopOnContainers) .NET reference application. @@ -11,29 +9,46 @@ This reference app is a "radified" version of the [eShop on containers](https:// 1. Have a kubernetes cluster handy from the [supported clusters](https://docs.radapp.io/guides/operations/kubernetes/overview/#supported-kubernetes-clusters). - (AWS only) Make sure that each of the Subnets in your EKS cluster Subnet Group are within the list of [supported MemoryDB availability zones](https://docs.aws.amazon.com/memorydb/latest/devguide/subnetgroups.html) 1. [Install the rad CLI](https://docs.radapp.io/getting-started/) -1. [Initialize a new Radius environment](https://docs.radapp.io/getting-started/) +1. Install Radius: + ```bash + rad install kubernetes + ``` +1. Set provider credentials to authenticate to your cloud provider (choose which type of hosting infrastructure you wish to use): + ```bash + # AWS + rad credential register aws --aws-access-key-id --aws-secret-access-key + + # Azure + rad credential register azure --client-id --client-secret --tenant-id + ``` 1. Clone the repository and switch to the app directory: ```bash git clone https://github.com/radius-project/samples.git cd samples/reference-apps/eshop ``` -1. Deploy the app (choose which type of hosting infrastructure you wish to use): - - ### Containerized infrastructure - - ```bash - rad deploy iac/eshop.bicep - ``` - - ### Azure infrastructure - - ```bash - rad deploy iac/eshop.bicep -p platform=azure - ``` - - ### AWS infrastructure - - ```bash - rad deploy iac/eshop.bicep -p platform=aws -p eksClusterName= - ``` - +1. Deploy an environment with the proper Recipes (choose which type of hosting infrastructure you wish to use): + ```bash + # Containers - simply initialize a new local-dev environment + rad init + + # Azure + rad deploy environments/azure.bicep -p azureSubscriptionId= -p azureResourceGroup= + + # AWS + rad deploy environments/aws.bicep -p awsAccountId= -p awsRegion= -p eksClusterName= + ``` +1. Switch to your new environment (choose which type of hosting infrastructure you wish to use): + ```bash + # Containers + rad env switch default + + # Azure + rad env switch azure + + # AWS + rad env switch aws + ``` +1. Deploy the application: + ```bash + rad deploy eshop.bicep + ``` diff --git a/samples/eshop/environments/aws.bicep b/samples/eshop/environments/aws.bicep new file mode 100644 index 00000000..3b492689 --- /dev/null +++ b/samples/eshop/environments/aws.bicep @@ -0,0 +1,54 @@ +import radius as rad + +@description('Account ID of the AWS account resources should be deployed in') +param awsAccountId string + +@description('AWS region that resources should be deployed in') +param awsRegion string + +@description('Name of your EKS cluster') +param eksClusterName string + +resource environment 'Applications.Core/environments@2023-10-01-preview' = { + name: 'aws' + properties: { + compute: { + kind: 'kubernetes' + resourceId: 'self' + namespace: 'aws' + } + providers: { + aws: { + scope: '/planes/aws/aws/accounts/${awsAccountId}/regions/${awsRegion}' + } + } + recipes: { + 'Applications.Datastores/sqlDatabases': { + default: { + templateKind: 'bicep' + templatePath: 'ghcr.io/radius-project/recipes/aws/sqldatabases:latest' + parameters: { + eksClusterName: eksClusterName + } + } + } + 'Applications.Datastores/redisCaches': { + default: { + templateKind: 'bicep' + templatePath: 'ghcr.io/radius-project/recipes/aws/rediscaches:latest' + parameters: { + eksClusterName: eksClusterName + } + } + } + // Use containerized RabbitMQ instead of Amazon SQS + // https://github.com/radius-project/bicep-types-aws/blob/main/docs/reference/limitations.md + 'Applications.Messaging/rabbitMQQueues': { + default: { + templateKind: 'bicep' + templatePath: 'ghcr.io/radius-project/recipes/local-dev/rabbitmqqueues:latest' + } + } + } + } +} diff --git a/samples/eshop/environments/azure.bicep b/samples/eshop/environments/azure.bicep new file mode 100644 index 00000000..a796cd24 --- /dev/null +++ b/samples/eshop/environments/azure.bicep @@ -0,0 +1,43 @@ +import radius as rad + +@description('The name of the Azure resource group where Azure resources will be deployed.') +param azureResourceGroup string + +@description('The Azure subscription ID where Azure resources will be deployed.') +param azureSubscriptionId string + +resource environment 'Applications.Core/environments@2023-10-01-preview' = { + name: 'azure' + properties: { + compute: { + kind: 'kubernetes' + resourceId: 'self' + namespace: 'azure' + } + providers: { + azure: { + scope: '/subscriptions/${azureSubscriptionId}/resourceGroups/${azureResourceGroup}' + } + } + recipes: { + 'Applications.Datastores/sqlDatabases': { + default: { + templateKind: 'bicep' + templatePath: 'ghcr.io/radius-project/recipes/azure/sqldatabases:latest' + } + } + 'Applications.Datastores/redisCaches': { + default: { + templateKind: 'bicep' + templatePath: 'ghcr.io/radius-project/recipes/azure/rediscaches:latest' + } + } + 'Applications.Core/extenders': { + servicebus: { + templateKind: 'bicep' + templatePath: 'ghcr.io/radius-project/recipes/azure/extender-servicebus:latest' + } + } + } + } +} diff --git a/samples/eshop/eshop.bicep b/samples/eshop/eshop.bicep new file mode 100644 index 00000000..3492f7a4 --- /dev/null +++ b/samples/eshop/eshop.bicep @@ -0,0 +1,220 @@ +import radius as rad + +// Parameters ------------------------------------------------------- + +@description('Radius environment ID. Set automatically by Radius') +param environment string + +@description('Container registry to pull from, with optional path. Defaults to "ghcr.io/radius-project/samples/eshop"') +param imageRegistry string = 'ghcr.io/radius-project/samples/eshop' + +@description('Container image tag to use for eshop images. Defaults to "latest".') +param imageTag string = 'latest' + +// Variables --------------------------------------------------------- + +// Get the environment name from the environment ID +var environmentName = last(split(environment, '/')) +resource eshopEnvironment 'Applications.Core/environments@2023-10-01-preview' existing = { + name: environmentName +} + +// Check if the environment has the rabbitmqqueues recipe registered +// If it does not, use Azure ServiceBus +var AZURESERVICEBUSENABLED = contains(eshopEnvironment.properties.recipes, 'Applications.Messaging/rabbitmqqueues') ? 'False' : 'True' + +// Application -------------------------------------------------------- + +resource eshopApplication 'Applications.Core/applications@2023-10-01-preview' = { + name: 'eshop' + properties: { + environment: environment + } +} + +// Infrastructure ------------------------------------------------------ + +module infra 'infra/infra.bicep' = { + name: 'infra' + params: { + application: eshopApplication.id + environment: environment + AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED + } +} + +// Networking ---------------------------------------------------------- + +module networking 'infra/networking.bicep' = { + name: 'networking' + params: { + application: eshopApplication.id + } +} + +// Services ------------------------------------------------------------ + +module basket 'services/basket.bicep' = { + name: 'basket' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + gatewayName: networking.outputs.gateway + identityHttpName: networking.outputs.identityHttp + basketHttpName: networking.outputs.basketHttp + basketGrpcName: networking.outputs.basketGrpc + redisBasketName: infra.outputs.redisBasket + eventBusConnectionString: infra.outputs.eventBusConnectionString + AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED + } +} + +module catalog 'services/catalog.bicep' = { + name: 'catalog' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + catalogGrpcName: networking.outputs.catalogGrpc + catalogHttpName: networking.outputs.catalogHttp + gatewayName: networking.outputs.gateway + sqlCatalogDbName: infra.outputs.sqlCatalogDb + eventBusConnectionString: infra.outputs.eventBusConnectionString + AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED + } +} + +module identity 'services/identity.bicep' = { + name: 'identity' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + basketHttpName: networking.outputs.basketHttp + gatewayName: networking.outputs.gateway + identityHttpName: networking.outputs.identityHttp + orderingHttpName: networking.outputs.orderingHttp + redisKeystoreName: infra.outputs.redisKeystore + sqlIdentityDbName: infra.outputs.sqlIdentityDb + webhooksclientHttpName: networking.outputs.webhooksclientHttp + webhooksHttpName: networking.outputs.webhooksHttp + webmvcHttpName: networking.outputs.webmvcHttp + webshoppingaggHttpName: networking.outputs.webshoppingaggHttp + } +} + +module ordering 'services/ordering.bicep' = { + name: 'ordering' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + basketHttpName: networking.outputs.basketHttp + catalogHttpName: networking.outputs.catalogHttp + gatewayName: networking.outputs.gateway + identityHttpName: networking.outputs.identityHttp + orderbgtasksHttpName: networking.outputs.orderbgtasksHttp + orderingGrpcName: networking.outputs.orderingGrpc + orderingHttpName: networking.outputs.orderingHttp + orderingsignalrhubHttpName: networking.outputs.orderingsignalrhubHttp + redisKeystoreName: infra.outputs.redisKeystore + sqlOrderingDbName: infra.outputs.sqlOrderingDb + eventBusConnectionString: infra.outputs.eventBusConnectionString + AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED + } +} + +module payment 'services/payment.bicep' = { + name: 'payment' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + paymentHttpName: networking.outputs.paymentHttp + eventBusConnectionString: infra.outputs.eventBusConnectionString + AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED + } +} + +module seq 'services/seq.bicep' = { + name: 'seq' + params: { + application: eshopApplication.id + seqHttpName: networking.outputs.seqHttp + } +} + +module web 'services/web.bicep' = { + name: 'web' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + gatewayName: networking.outputs.gateway + identityHttpName: networking.outputs.identityHttp + orderingsignalrhubHttpName: networking.outputs.orderingsignalrhubHttp + redisKeystoreName: infra.outputs.redisKeystore + webmvcHttpName: networking.outputs.webmvcHttp + webshoppingaggHttpName: networking.outputs.webshoppingaggHttp + webshoppingapigwHttpName: networking.outputs.webshoppingapigwHttp + webspaHttpName: networking.outputs.webspaHttp + } +} + +module webhooks 'services/webhooks.bicep' = { + name: 'webhooks' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + gatewayName: networking.outputs.gateway + identityHttpName: networking.outputs.identityHttp + sqlWebhooksDbName: infra.outputs.sqlWebhooksDb + webhooksclientHttpName: networking.outputs.webhooksclientHttp + webhooksHttpName: networking.outputs.webhooksHttp + eventBusConnectionString: infra.outputs.eventBusConnectionString + AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED + } +} + +module webshopping 'services/webshopping.bicep' = { + name: 'webshopping' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + basketGrpcName: networking.outputs.basketGrpc + basketHttpName: networking.outputs.basketHttp + catalogGrpcName: networking.outputs.catalogGrpc + catalogHttpName: networking.outputs.catalogHttp + gatewayName: networking.outputs.gateway + identityHttpName: networking.outputs.identityHttp + orderingGrpcName: networking.outputs.orderingGrpc + orderingHttpName: networking.outputs.basketHttp + paymentHttpName: networking.outputs.paymentHttp + webshoppingaggHttpName: networking.outputs.webshoppingaggHttp + webshoppingapigwHttp2Name: networking.outputs.webshoppingapigwHttp2 + webshoppingapigwHttpName: networking.outputs.webshoppingapigwHttp + } +} + +module webstatus 'services/webstatus.bicep' = { + name: 'webstatus' + params: { + application: eshopApplication.id + imageRegistry: imageRegistry + imageTag: imageTag + basketHttpName: networking.outputs.basketHttp + catalogHttpName: networking.outputs.catalogHttp + identityHttpName: networking.outputs.identityHttp + orderbgtasksHttpName: networking.outputs.orderbgtasksHttp + orderingHttpName: networking.outputs.orderingHttp + orderingsignalrhubHttpName: networking.outputs.orderingsignalrhubHttp + paymentHttpName: networking.outputs.paymentHttp + webmvcHttpName: networking.outputs.webmvcHttp + webshoppingaggHttpName: networking.outputs.webshoppingaggHttp + webspaHttpName: networking.outputs.webspaHttp + webstatusHttpName: networking.outputs.webstatusHttp + } +} diff --git a/samples/eshop/iac/eshop.bicep b/samples/eshop/iac/eshop.bicep deleted file mode 100644 index 2c7444f4..00000000 --- a/samples/eshop/iac/eshop.bicep +++ /dev/null @@ -1,301 +0,0 @@ -import radius as rad - -// Paramaters ------------------------------------------------------- - -@description('Name of the eshop application. Defaults to "eshop"') -param appName string = 'eshop' - -@description('Radius environment ID. Set automatically by Radius') -param environment string - -@description('What type of infrastructure to use. Options are "containers", "azure", or "aws". Defaults to containers') -@allowed([ - 'containers' - 'azure' - 'aws' -]) -param platform string = 'containers' - -@description('SQL administrator username') -param adminLogin string = (platform == 'containers') ? 'SA' : 'sqladmin' - -@description('SQL administrator password') -@secure() -param adminPassword string = newGuid() - -@description('What container orchestrator to use. Defaults to K8S') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string = 'K8S' - -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string = '' - -@description('Use Azure storage for custom resource images. Defaults to False') -@allowed([ - 'True' - 'False' -]) -param AZURESTORAGEENABLED string = 'False' - -var AZURESERVICEBUSENABLED = (platform == 'azure') ? 'True' : 'False' - -@description('Use dev spaces. Defaults to False') -@allowed([ - 'True' - 'False' -]) -param ENABLEDEVSPACES string = 'False' - -@description('Container image tag to use for eshop images') -param TAG string = 'latest' - -@description('Name of your EKS cluster. Only used if deploying with AWS infrastructure.') -param eksClusterName string = '' - -// Application -------------------------------------------------------- - -resource eshop 'Applications.Core/applications@2023-10-01-preview' = { - name: appName - properties: { - environment: environment - } -} - -// Infrastructure ------------------------------------------------------ - -module containers 'infra/containers.bicep' = if (platform == 'containers') { - name: 'containers' - params: { - application: eshop.id - environment: environment - adminPassword: adminPassword - } -} - -module azure 'infra/azure.bicep' = if (platform == 'azure') { - name: 'azure' - // Temporarily disable linter rule until deployment engine returns Azure resource group location instead of UCP resource group location - #disable-next-line explicit-values-for-loc-params - params: { - application: eshop.id - environment: environment - adminLogin: adminLogin - adminPassword: adminPassword - } -} - -module aws 'infra/aws.bicep' = if (platform == 'aws') { - name: 'aws' - params: { - application: eshop.id - eksClusterName: eksClusterName - environment: environment - adminLogin: adminLogin - adminPassword: adminPassword - applicationName: appName - } -} - -// Portable Resources ----------------------------------------------------------- -// TODO: Switch to Recipes once ready - -module links 'infra/links.bicep' = { - name: 'links' - dependsOn: [ - containers - azure - aws - ] -} - -// Networking ---------------------------------------------------------- - -module networking 'services/networking.bicep' = { - name: 'networking' - params: { - application: eshop.id - } -} - -// Services ------------------------------------------------------------ - -module basket 'services/basket.bicep' = { - name: 'basket' - params: { - application: eshop.id - APPLICATION_INSIGHTS_KEY: APPLICATION_INSIGHTS_KEY - AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - gatewayName: networking.outputs.gateway - identityHttpName: networking.outputs.identityHttp - basketHttpName: networking.outputs.basketHttp - basketGrpcName: networking.outputs.basketGrpc - rabbitmqName: links.outputs.rabbitmq - redisBasketName: links.outputs.redisBasket - TAG: TAG - serviceBusConnectionString: (AZURESERVICEBUSENABLED == 'True') ? azure.outputs.serviceBusAuthConnectionString : '' - } -} - -module catalog 'services/catalog.bicep' = { - name: 'catalog' - params: { - application: eshop.id - APPLICATION_INSIGHTS_KEY: APPLICATION_INSIGHTS_KEY - AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED - AZURESTORAGEENABLED: AZURESTORAGEENABLED - catalogGrpcName: networking.outputs.catalogGrpc - catalogHttpName: networking.outputs.catalogHttp - gatewayName: networking.outputs.gateway - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - rabbitmqName: links.outputs.rabbitmq - sqlCatalogDbName: links.outputs.sqlCatalogDb - TAG: TAG - serviceBusConnectionString: (AZURESERVICEBUSENABLED == 'True') ? azure.outputs.serviceBusAuthConnectionString : '' - } -} - -module identity 'services/identity.bicep' = { - name: 'identity' - params: { - application: eshop.id - APPLICATION_INSIGHTS_KEY: APPLICATION_INSIGHTS_KEY - basketHttpName: networking.outputs.basketHttp - ENABLEDEVSPACES: ENABLEDEVSPACES - gatewayName: networking.outputs.gateway - identityHttpName: networking.outputs.identityHttp - orderingHttpName: networking.outputs.orderingHttp - redisKeystoreName: links.outputs.redisKeystore - sqlIdentityDbName: links.outputs.sqlIdentityDb - TAG: TAG - webhooksclientHttpName: networking.outputs.webhooksclientHttp - webhooksHttpName: networking.outputs.webhooksHttp - webmvcHttpName: networking.outputs.webmvcHttp - webshoppingaggHttpName: networking.outputs.webshoppingaggHttp - } -} - -module ordering 'services/ordering.bicep' = { - name: 'ordering' - params: { - application: eshop.id - APPLICATION_INSIGHTS_KEY: APPLICATION_INSIGHTS_KEY - AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED - basketHttpName: networking.outputs.basketHttp - catalogHttpName: networking.outputs.catalogHttp - gatewayName: networking.outputs.gateway - identityHttpName: networking.outputs.identityHttp - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - orderbgtasksHttpName: networking.outputs.orderbgtasksHttp - orderingGrpcName: networking.outputs.orderingGrpc - orderingHttpName: networking.outputs.orderingHttp - orderingsignalrhubHttpName: networking.outputs.orderingsignalrhubHttp - rabbitmqName: links.outputs.rabbitmq - redisKeystoreName: links.outputs.redisKeystore - sqlOrderingDbName: links.outputs.sqlOrderingDb - TAG: TAG - serviceBusConnectionString: (AZURESERVICEBUSENABLED == 'True') ? azure.outputs.serviceBusAuthConnectionString : '' - } -} - -module payment 'services/payment.bicep' = { - name: 'payment' - params: { - application: eshop.id - APPLICATION_INSIGHTS_KEY: APPLICATION_INSIGHTS_KEY - AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - paymentHttpName: networking.outputs.paymentHttp - rabbitmqName: links.outputs.rabbitmq - TAG: TAG - serviceBusConnectionString: (AZURESERVICEBUSENABLED == 'True') ? azure.outputs.serviceBusAuthConnectionString : '' - } -} - -module seq 'services/seq.bicep' = { - name: 'seq' - params: { - application: eshop.id - seqHttpName: networking.outputs.seqHttp - } -} - -module web 'services/web.bicep' = { - name: 'web' - params: { - application: eshop.id - APPLICATION_INSIGHTS_KEY: APPLICATION_INSIGHTS_KEY - gatewayName: networking.outputs.gateway - identityHttpName: networking.outputs.identityHttp - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - orderingsignalrhubHttpName: networking.outputs.orderingsignalrhubHttp - redisKeystoreName: links.outputs.redisKeystore - TAG: TAG - webmvcHttpName: networking.outputs.webmvcHttp - webshoppingaggHttpName: networking.outputs.webshoppingaggHttp - webshoppingapigwHttpName: networking.outputs.webshoppingapigwHttp - webspaHttpName: networking.outputs.webspaHttp - } -} - -module webhooks 'services/webhooks.bicep' = { - name: 'webhooks' - params: { - application: eshop.id - AZURESERVICEBUSENABLED: AZURESERVICEBUSENABLED - gatewayName: networking.outputs.gateway - identityHttpName: networking.outputs.identityHttp - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - rabbitmqName: links.outputs.rabbitmq - sqlWebhooksDbName: links.outputs.sqlWebhooksDb - TAG: TAG - webhooksclientHttpName: networking.outputs.webhooksclientHttp - webhooksHttpName: networking.outputs.webhooksHttp - serviceBusConnectionString: (AZURESERVICEBUSENABLED == 'True') ? azure.outputs.serviceBusAuthConnectionString : '' - } -} - -module webshopping 'services/webshopping.bicep' = { - name: 'webshopping' - params: { - application: eshop.id - basketGrpcName: networking.outputs.basketGrpc - basketHttpName: networking.outputs.basketHttp - catalogGrpcName: networking.outputs.catalogGrpc - catalogHttpName: networking.outputs.catalogHttp - gatewayName: networking.outputs.gateway - identityHttpName: networking.outputs.identityHttp - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - orderingGrpcName: networking.outputs.orderingGrpc - orderingHttpName: networking.outputs.basketHttp - paymentHttpName: networking.outputs.paymentHttp - rabbitmqName: links.outputs.rabbitmq - TAG: TAG - webshoppingaggHttpName: networking.outputs.webshoppingaggHttp - webshoppingapigwHttp2Name: networking.outputs.webshoppingapigwHttp2 - webshoppingapigwHttpName: networking.outputs.webshoppingapigwHttp - } -} - -module webstatus 'services/webstatus.bicep' = { - name: 'webstatus' - params: { - application: eshop.id - APPLICATION_INSIGHTS_KEY: APPLICATION_INSIGHTS_KEY - basketHttpName: networking.outputs.basketHttp - catalogHttpName: networking.outputs.catalogHttp - identityHttpName: networking.outputs.identityHttp - ORCHESTRATOR_TYPE: ORCHESTRATOR_TYPE - orderbgtasksHttpName: networking.outputs.orderbgtasksHttp - orderingHttpName: networking.outputs.orderingHttp - orderingsignalrhubHttpName: networking.outputs.orderingsignalrhubHttp - paymentHttpName: networking.outputs.paymentHttp - TAG: TAG - webmvcHttpName: networking.outputs.webmvcHttp - webshoppingaggHttpName: networking.outputs.webshoppingaggHttp - webspaHttpName: networking.outputs.webspaHttp - webstatusHttpName: networking.outputs.webstatusHttp - } -} diff --git a/samples/eshop/iac/infra/aws.bicep b/samples/eshop/iac/infra/aws.bicep deleted file mode 100644 index 23180522..00000000 --- a/samples/eshop/iac/infra/aws.bicep +++ /dev/null @@ -1,379 +0,0 @@ -import radius as radius -import aws as aws - -@description('Radius environment ID') -param environment string - -@description('Radius application ID') -param application string - -@description('Radius application name') -param applicationName string - -@description('SQL administrator username') -param adminLogin string - -@description('SQL administrator password') -@secure() -param adminPassword string - -@description('Name of the EKS cluster where the application will be run. Used to setup subnet groups') -param eksClusterName string - -// Infrastructure ------------------------------------------------------------ - -resource eksCluster 'AWS.EKS/Cluster@default' existing = { - alias: eksClusterName - properties: { - Name: eksClusterName - } -} - -var sqlSubnetGroupName = 'eshopsqlsg${uniqueString(application)}' -resource sqlSubnetGroup 'AWS.RDS/DBSubnetGroup@default' = { - alias: sqlSubnetGroupName - properties: { - DBSubnetGroupName: sqlSubnetGroupName - DBSubnetGroupDescription: sqlSubnetGroupName - SubnetIds: eksCluster.properties.ResourcesVpcConfig.SubnetIds - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -var identityDbIdentifier = 'eshopidentitysql${uniqueString(application)}' -resource identityDb 'AWS.RDS/DBInstance@default' = { - alias: identityDbIdentifier - properties: { - DBInstanceIdentifier: identityDbIdentifier - Engine: 'sqlserver-ex' - EngineVersion: '15.00.4153.1.v1' - DBInstanceClass: 'db.t3.large' - AllocatedStorage: '20' - MaxAllocatedStorage: 30 - MasterUsername: adminLogin - MasterUserPassword: adminPassword - Port: '1433' - DBSubnetGroupName: sqlSubnetGroup.properties.DBSubnetGroupName - VPCSecurityGroups: [eksCluster.properties.ClusterSecurityGroupId] - PreferredMaintenanceWindow: 'Mon:00:00-Mon:03:00' - PreferredBackupWindow: '03:00-06:00' - LicenseModel: 'license-included' - Timezone: 'GMT Standard Time' - CharacterSetName: 'Latin1_General_CI_AS' - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -var catalogDbIdentifier = 'eshopcatalogsql${uniqueString(application)}' -resource catalogDb 'AWS.RDS/DBInstance@default' = { - alias: catalogDbIdentifier - properties: { - DBInstanceIdentifier: catalogDbIdentifier - Engine: 'sqlserver-ex' - EngineVersion: '15.00.4153.1.v1' - DBInstanceClass: 'db.t3.large' - AllocatedStorage: '20' - MaxAllocatedStorage: 30 - MasterUsername: adminLogin - MasterUserPassword: adminPassword - Port: '1433' - DBSubnetGroupName: sqlSubnetGroup.properties.DBSubnetGroupName - VPCSecurityGroups: [eksCluster.properties.ClusterSecurityGroupId] - PreferredMaintenanceWindow: 'Mon:00:00-Mon:03:00' - PreferredBackupWindow: '03:00-06:00' - LicenseModel: 'license-included' - Timezone: 'GMT Standard Time' - CharacterSetName: 'Latin1_General_CI_AS' - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -var orderingDbIdentifier = 'eshoporderingsql${uniqueString(application)}' -resource orderingDb 'AWS.RDS/DBInstance@default' = { - alias: orderingDbIdentifier - properties: { - DBInstanceIdentifier: orderingDbIdentifier - Engine: 'sqlserver-ex' - EngineVersion: '15.00.4153.1.v1' - DBInstanceClass: 'db.t3.large' - AllocatedStorage: '20' - MaxAllocatedStorage: 30 - MasterUsername: adminLogin - MasterUserPassword: adminPassword - Port: '1433' - DBSubnetGroupName: sqlSubnetGroup.properties.DBSubnetGroupName - VPCSecurityGroups: [eksCluster.properties.ClusterSecurityGroupId] - PreferredMaintenanceWindow: 'Mon:00:00-Mon:03:00' - PreferredBackupWindow: '03:00-06:00' - LicenseModel: 'license-included' - Timezone: 'GMT Standard Time' - CharacterSetName: 'Latin1_General_CI_AS' - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -var webhooksDbIdentifier = 'eshopwebhookssql${uniqueString(application)}' -resource webhooksDb 'AWS.RDS/DBInstance@default' = { - alias: webhooksDbIdentifier - properties: { - DBInstanceIdentifier: webhooksDbIdentifier - Engine: 'sqlserver-ex' - EngineVersion: '15.00.4153.1.v1' - DBInstanceClass: 'db.t3.large' - AllocatedStorage: '20' - MaxAllocatedStorage: 30 - MasterUsername: adminLogin - MasterUserPassword: adminPassword - Port: '1433' - DBSubnetGroupName: sqlSubnetGroup.properties.DBSubnetGroupName - VPCSecurityGroups: [eksCluster.properties.ClusterSecurityGroupId] - PreferredMaintenanceWindow: 'Mon:00:00-Mon:03:00' - PreferredBackupWindow: '03:00-06:00' - LicenseModel: 'license-included' - Timezone: 'GMT Standard Time' - CharacterSetName: 'Latin1_General_CI_AS' - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -var redisSubnetGroupName = 'eshopredissg${uniqueString(application)}' -resource redisSubnetGroup 'AWS.MemoryDB/SubnetGroup@default' = { - alias: redisSubnetGroupName - properties: { - SubnetGroupName: redisSubnetGroupName - SubnetIds: eksCluster.properties.ResourcesVpcConfig.SubnetIds - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -var keystoreCacheName = 'eshopkeystore${uniqueString(application)}' -resource keystoreCache 'AWS.MemoryDB/Cluster@default' = { - alias: keystoreCacheName - properties: { - ClusterName: keystoreCacheName - NodeType: 'db.t4g.small' - ACLName: 'open-access' - SecurityGroupIds: [eksCluster.properties.ClusterSecurityGroupId] - SubnetGroupName: redisSubnetGroup.properties.SubnetGroupName - NumReplicasPerShard: 0 - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -var basketCacheName = 'eshopbasket${uniqueString(application)}' -resource basketCache 'AWS.MemoryDB/Cluster@default' = { - alias: basketCacheName - properties: { - ClusterName: basketCacheName - NodeType: 'db.t4g.small' - ACLName: 'open-access' - SecurityGroupIds: [eksCluster.properties.ClusterSecurityGroupId] - SubnetGroupName: redisSubnetGroup.name - NumReplicasPerShard: 0 - Tags: [ - { - Key: 'RadiusApplication' - Value: applicationName - } - ] - } -} - -// TEMP: Using containerized rabbitMQ instead of AWS SNS until AWS nonidempotency is resolved -resource rabbitmqContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'rabbitmq-container-eshop-event-bus' - properties: { - application: application - container: { - image: 'rabbitmq:3.9' - env: {} - ports: { - rabbitmq: { - containerPort: 5672 - provides: rabbitmqRoute.id - } - } - } - } -} - -resource rabbitmqRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'rabbitmq-route-eshop-event-bus' - properties: { - application: application - port: 5672 - } -} - -// Portable Resources ---------------------------------------------------------------------------- -// TODO: Move the portable resource definitions into the application and use Recipes instead - -resource sqlIdentityDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'identitydb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: 'IdentityDb' - server: identityDb.properties.Endpoint.Address - port: int(identityDb.properties.Endpoint.Port) - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${identityDb.properties.Endpoint.Address},${identityDb.properties.Endpoint.Port};Initial Catalog=IdentityDb;User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - } -} - -resource sqlCatalogDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'catalogdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: 'CatalogDb' - server: catalogDb.properties.Endpoint.Address - port: int(catalogDb.properties.Endpoint.Port) - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${catalogDb.properties.Endpoint.Address},${catalogDb.properties.Endpoint.Port};Initial Catalog=CatalogDb;User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - } -} - -resource sqlOrderingDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'orderingdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: 'OrderingDb' - server: orderingDb.properties.Endpoint.Address - port: int(orderingDb.properties.Endpoint.Port) - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${orderingDb.properties.Endpoint.Address},${orderingDb.properties.Endpoint.Port};Initial Catalog=OrderingDb;User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - } -} - -resource sqlWebhooksDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'webhooksdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: 'WebhooksDb' - server: webhooksDb.properties.Endpoint.Address - port: int(webhooksDb.properties.Endpoint.Port) - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${webhooksDb.properties.Endpoint.Address},${webhooksDb.properties.Endpoint.Port};Initial Catalog=WebhooksDb;User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - } -} - -resource redisKeystore 'Applications.Datastores/redisCaches@2023-10-01-preview' = { - name: 'keystore-data' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - host: keystoreCache.properties.ClusterEndpoint.Address - port: keystoreCache.properties.ClusterEndpoint.Port - secrets: { - connectionString: '${keystoreCache.properties.ClusterEndpoint.Address}:${keystoreCache.properties.ClusterEndpoint.Port},ssl=true' - } - } -} - -resource redisBasket 'Applications.Datastores/redisCaches@2023-10-01-preview' = { - name: 'basket-data' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - host: basketCache.properties.ClusterEndpoint.Address - port: basketCache.properties.ClusterEndpoint.Port - secrets: { - connectionString: '${basketCache.properties.ClusterEndpoint.Address}:${basketCache.properties.ClusterEndpoint.Port},ssl=true' - } - } -} - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' = { - name: 'eshop-event-bus' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - queue: 'eshop-event-bus' - host: rabbitmqRoute.properties.hostname - port: rabbitmqRoute.properties.port - username: 'guest' - secrets: { - password: 'guest' - } - } -} - -// Outputs ------------------------------------ - -@description('The name of the SQL Identity portable resource') -output sqlIdentityDb string = sqlIdentityDb.name - -@description('The name of the SQL Catalog portable resource') -output sqlCatalogDb string = sqlCatalogDb.name - -@description('The name of the SQL Ordering portable resource') -output sqlOrderingDb string = sqlOrderingDb.name - -@description('The name of the SQL Webhooks portable resource') -output sqlWebhooksDb string = sqlWebhooksDb.name - -@description('The name of the Redis Keystore portable resource') -output redisKeystore string = redisKeystore.name - -@description('The name of the Redis Basket portable resource') -output redisBasket string = redisBasket.name - -@description('The name of the RabbitMQ portable resource') -output rabbitmq string = rabbitmq.name diff --git a/samples/eshop/iac/infra/azure.bicep b/samples/eshop/iac/infra/azure.bicep deleted file mode 100644 index e2817a0b..00000000 --- a/samples/eshop/iac/infra/azure.bicep +++ /dev/null @@ -1,400 +0,0 @@ -import radius as rad -import az as az - -@description('Azure region to deploy resources into') -param location string = resourceGroup().location - -@description('Radius environment ID') -param environment string - -@description('Radius application ID') -param application string - -@description('SQL administrator username') -param adminLogin string - -@description('SQL administrator password') -@secure() -param adminPassword string - -var sqlPort = 1433 - -// Infrastructure ------------------------------------------------------------ -// TODO: Move the infrastructure into Recipes - -resource servicebus 'Microsoft.ServiceBus/namespaces@2021-06-01-preview' = { - name: 'eshop${uniqueString(resourceGroup().id)}' - location: location - sku: { - name: 'Standard' - tier: 'Standard' - } - - resource topic 'topics' = { - name: 'eshop_event_bus' - properties: { - defaultMessageTimeToLive: 'P14D' - maxSizeInMegabytes: 1024 - requiresDuplicateDetection: false - enableBatchedOperations: true - supportOrdering: false - enablePartitioning: true - enableExpress: false - } - - resource rootRule 'authorizationRules' = { - name: 'Root' - properties: { - rights: [ - 'Manage' - 'Send' - 'Listen' - ] - } - } - - resource basket 'subscriptions' = { - name: 'Basket' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - resource catalog 'subscriptions' = { - name: 'Catalog' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - resource ordering 'subscriptions' = { - name: 'Ordering' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - resource graceperiod 'subscriptions' = { - name: 'GracePeriod' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - resource payment 'subscriptions' = { - name: 'Payment' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - resource backgroundTasks 'subscriptions' = { - name: 'backgroundtasks' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - resource OrderingSignalrHub 'subscriptions' = { - name: 'Ordering.signalrhub' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - resource webhooks 'subscriptions' = { - name: 'Webhooks' - properties: { - requiresSession: false - defaultMessageTimeToLive: 'P14D' - deadLetteringOnMessageExpiration: true - deadLetteringOnFilterEvaluationExceptions: true - maxDeliveryCount: 10 - enableBatchedOperations: true - } - } - - } - -} - -resource sql 'Microsoft.Sql/servers@2021-02-01-preview' = { - name: 'eshopsql${uniqueString(resourceGroup().id)}' - location: location - properties: { - administratorLogin: adminLogin - administratorLoginPassword: adminPassword - } - - resource allowEverything 'firewallRules' = { - name: 'allow-everrything' - properties: { - startIpAddress: '0.0.0.0' - endIpAddress: '255.255.255.255' - } - } - - resource identityDb 'databases' = { - name: 'IdentityDb' - location: location - sku: { - name: 'Standard' - tier: 'Standard' - } - } - - resource catalogDb 'databases' = { - name: 'CatalogDb' - location: location - sku: { - name: 'Standard' - tier: 'Standard' - } - } - - resource orderingDb 'databases' = { - name: 'OrderingDb' - location: location - sku: { - name: 'Standard' - tier: 'Standard' - } - } - - resource webhooksDb 'databases' = { - name: 'WebhooksDb' - location: location - sku: { - name: 'Standard' - tier: 'Standard' - } - } - -} - -resource keystoreCache 'Microsoft.Cache/redis@2020-12-01' = { - name: 'eshopkeystore${uniqueString(resourceGroup().id)}' - location: location - properties: { - enableNonSslPort: false - minimumTlsVersion: '1.2' - sku: { - family: 'C' - capacity: 1 - name: 'Basic' - } - } -} - -resource basketCache 'Microsoft.Cache/redis@2020-12-01' = { - name: 'eshopbasket${uniqueString(resourceGroup().id)}' - location: location - properties: { - enableNonSslPort: false - minimumTlsVersion: '1.2' - sku: { - family: 'C' - capacity: 1 - name: 'Basic' - } - } -} - -// Portable Resources ---------------------------------------------------------------------------- -// TODO: Move the portable resource definitions into the application and use Recipes instead - -// Need to deploy a blank rabbitmq instance to let Bicep successfully deploy -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' = { - name: 'eshop-event-bus' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - queue: 'eshop-event-bus' - host: 'test' - port: 5672 - secrets: { - uri: 'test' - } - } -} - -resource sqlIdentityDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'identitydb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: sql::identityDb.name - server: sql.properties.fullyQualifiedDomainName - port: sqlPort - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sql.properties.fullyQualifiedDomainName},${sqlPort};Initial Catalog=${sql::identityDb.name};User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - resources: [ - { - id: sql::identityDb.id - } - ] - } -} - -resource sqlCatalogDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'catalogdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: sql::catalogDb.name - server: sql.properties.fullyQualifiedDomainName - port: sqlPort - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sql.properties.fullyQualifiedDomainName},${sqlPort};Initial Catalog=${sql::catalogDb.name};User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - resources: [ - { - id: sql::catalogDb.id - } - ] - } -} - -resource sqlOrderingDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'orderingdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: sql::orderingDb.name - server: sql.properties.fullyQualifiedDomainName - port: sqlPort - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sql.properties.fullyQualifiedDomainName},${sqlPort};Initial Catalog=${sql::orderingDb.name};User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - resources: [ - { - id: sql::orderingDb.id - } - ] - } -} - -resource sqlWebhooksDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'webhooksdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - database: sql::webhooksDb.name - server: sql.properties.fullyQualifiedDomainName - port: sqlPort - username: adminLogin - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sql.properties.fullyQualifiedDomainName},${sqlPort};Initial Catalog=${sql::webhooksDb.name};User Id=${adminLogin};Password=${adminPassword};Encrypt=false' - } - resources: [ - { - id: sql::webhooksDb.id - } - ] - } -} - -resource redisBasket 'Applications.Datastores/redisCaches@2023-10-01-preview' = { - name: 'basket-data' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - host: basketCache.properties.hostName - port: basketCache.properties.sslPort - secrets: { - password: basketCache.listKeys().primaryKey - connectionString: '${basketCache.properties.hostName}:${basketCache.properties.sslPort},password=${basketCache.listKeys().primaryKey},ssl=True,abortConnect=False' - } - } -} - -resource redisKeystore 'Applications.Datastores/redisCaches@2023-10-01-preview' = { - name: 'keystore-data' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - host: keystoreCache.properties.hostName - port: keystoreCache.properties.sslPort - secrets: { - password: keystoreCache.listKeys().primaryKey - connectionString: '${keystoreCache.properties.hostName}:${keystoreCache.properties.sslPort},password=${keystoreCache.listKeys().primaryKey},ssl=True,abortConnect=False' - } - } -} - -// Outputs ------------------------------------ - -@description('The ID of the auth rule') -#disable-next-line outputs-should-not-contain-secrets -output serviceBusAuthConnectionString string = servicebus::topic::rootRule.listKeys().primaryConnectionString - -@description('The name of the RabbitMQ Queue') -output rabbitMqQueue string = rabbitmq.name - -@description('The name of the SQL Identity portable resource') -output sqlIdentityDb string = sqlIdentityDb.name - -@description('The name of the SQL Catalog portable resource') -output sqlCatalogDb string = sqlCatalogDb.name - -@description('The name of the SQL Ordering portable resource') -output sqlOrderingDb string = sqlOrderingDb.name - -@description('The name of the SQL Webhooks portable resource') -output sqlWebhooksDb string = sqlWebhooksDb.name - -@description('The name of the Redis Keystore portable resource') -output redisKeystore string = redisKeystore.name - -@description('The name of the Redis Basket portable resource') -output redisBasket string = redisBasket.name diff --git a/samples/eshop/iac/infra/containers.bicep b/samples/eshop/iac/infra/containers.bicep deleted file mode 100644 index 75d975c6..00000000 --- a/samples/eshop/iac/infra/containers.bicep +++ /dev/null @@ -1,343 +0,0 @@ -import radius as rad - -@description('Radius environment ID') -param environment string - -@description('Radius application ID') -param application string - -@description('SQL administrator password') -@secure() -param adminPassword string - -var adminUsername = 'sa' - -// Infrastructure ------------------------------------------------- - -resource rabbitmqContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'rabbitmq-container-eshop-event-bus' - properties: { - application: application - container: { - image: 'rabbitmq:3.9' - env: {} - ports: { - rabbitmq: { - containerPort: 5672 - provides: rabbitmqRoute.id - } - } - } - } -} - -resource rabbitmqRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'rabbitmq-route-eshop-event-bus' - properties: { - application: application - port: 5672 - } -} - -resource sqlIdentityContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'sql-server-identitydb' - properties: { - application: application - container: { - image: 'mcr.microsoft.com/mssql/server:2019-latest' - env: { - ACCEPT_EULA: 'Y' - MSSQL_PID: 'Developer' - MSSQL_SA_PASSWORD: adminPassword - } - ports: { - sql: { - containerPort: 1433 - provides: sqlIdentityRoute.id - } - } - } - } -} - -resource sqlIdentityRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'sql-route-identitydb' - properties: { - application: application - port: 1433 - } -} - -resource sqlCatalogContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'sql-server-catalogdb' - properties: { - application: application - container: { - image: 'mcr.microsoft.com/mssql/server:2019-latest' - env: { - ACCEPT_EULA: 'Y' - MSSQL_PID: 'Developer' - MSSQL_SA_PASSWORD: adminPassword - } - ports: { - sql: { - containerPort: 1433 - provides: sqlCatalogRoute.id - } - } - } - } -} - -resource sqlCatalogRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'sql-route-catalogdb' - properties: { - application: application - port: 1433 - } -} - -resource sqlOrderingContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'sql-server-orderingdb' - properties: { - application: application - container: { - image: 'mcr.microsoft.com/mssql/server:2019-latest' - env: { - ACCEPT_EULA: 'Y' - MSSQL_PID: 'Developer' - MSSQL_SA_PASSWORD: adminPassword - } - ports: { - sql: { - containerPort: 1433 - provides: sqlOrderingRoute.id - } - } - } - } -} - -resource sqlOrderingRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'sql-route-orderingdb' - properties: { - application: application - port: 1433 - } -} - -resource sqlWebhooksContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'sql-server-webhooksdb' - properties: { - application: application - container: { - image: 'mcr.microsoft.com/mssql/server:2019-latest' - env: { - ACCEPT_EULA: 'Y' - MSSQL_PID: 'Developer' - MSSQL_SA_PASSWORD: adminPassword - } - ports: { - sql: { - containerPort: 1433 - provides: sqlWebhooksRoute.id - } - } - } - } -} - -resource sqlWebhooksRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'sql-route-webhooksdb' - properties: { - application: application - port: 1433 - } -} - -resource redisBasketContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'redis-container-basket-data' - properties: { - application: application - container: { - image: 'redis:6.2' - env: {} - ports: { - redis: { - containerPort: 6379 - provides: redisBasketRoute.id - } - } - } - } -} - -resource redisBasketRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'redis-route-basket-data' - properties: { - application: application - port: 6379 - } -} - -resource redisKeystoreContainer 'Applications.Core/containers@2023-10-01-preview' = { - name: 'redis-container-keystore-data' - properties: { - application: application - container: { - image: 'redis:6.2' - env: {} - ports: { - redis: { - containerPort: 6379 - provides: redisKeystoreRoute.id - } - } - } - } -} - -resource redisKeystoreRoute 'Applications.Core/httproutes@2023-10-01-preview' = { - name: 'redis-route-keystore-data' - properties: { - application: application - port: 6379 - } -} - -// Portable Resources --------------------------------------------------------------- - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' = { - name: 'eshop-event-bus' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - queue: 'eshop-event-bus' - host: rabbitmqRoute.properties.hostname - port: rabbitmqRoute.properties.port - username: 'guest' - secrets: { - password: 'guest' - } - } -} - -resource sqlIdentityDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'identitydb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - server: sqlIdentityRoute.properties.hostname - database: 'IdentityDb' - port: sqlIdentityRoute.properties.port - username: adminUsername - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sqlIdentityRoute.properties.hostname},${sqlIdentityRoute.properties.port};Initial Catalog=IdentityDb;User Id=${adminUsername};Password=${adminPassword};Encrypt=false' - } - } -} - -resource sqlCatalogDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'catalogdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - server: sqlCatalogRoute.properties.hostname - database: 'CatalogDb' - port: sqlCatalogRoute.properties.port - username: adminUsername - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sqlCatalogRoute.properties.hostname},${sqlCatalogRoute.properties.port};Initial Catalog=CatalogDb;User Id=${adminUsername};Password=${adminPassword};Encrypt=false' - } - } -} - -resource sqlOrderingDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'orderingdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - server: sqlOrderingRoute.properties.hostname - database: 'OrderingDb' - port: sqlOrderingRoute.properties.port - username: adminUsername - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sqlOrderingRoute.properties.hostname},${sqlOrderingRoute.properties.port};Initial Catalog=OrderingDb;User Id=${adminUsername};Password=${adminPassword};Encrypt=false' - } - } -} - -resource sqlWebhooksDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { - name: 'webhooksdb' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - server: sqlWebhooksRoute.properties.hostname - database: 'WebhooksDb' - port: sqlWebhooksRoute.properties.port - username: adminUsername - secrets: { - password: adminPassword - connectionString: 'Server=tcp:${sqlWebhooksRoute.properties.hostname},${sqlWebhooksRoute.properties.port};Initial Catalog=WebhooksDb;User Id=${adminUsername};Password=${adminPassword};Encrypt=false' - } - } -} - -resource redisBasket 'Applications.Datastores/redisCaches@2023-10-01-preview' = { - name: 'basket-data' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - host: redisBasketRoute.properties.hostname - port: redisBasketRoute.properties.port - secrets: { - connectionString: '${redisBasketRoute.properties.hostname}:${redisBasketRoute.properties.port},abortConnect=False' - } - } -} - -resource redisKeystore 'Applications.Datastores/redisCaches@2023-10-01-preview' = { - name: 'keystore-data' - properties: { - application: application - environment: environment - resourceProvisioning: 'manual' - host: redisKeystoreRoute.properties.hostname - port: redisKeystoreRoute.properties.port - secrets: { - connectionString: '${redisKeystoreRoute.properties.hostname}:${redisKeystoreRoute.properties.port},abortConnect=False' - } - } -} - -// Outputs ------------------------------------ - -@description('The name of the SQL Identity portable resource') -output sqlIdentityDb string = sqlIdentityDb.name - -@description('The name of the SQL Catalog portable resource') -output sqlCatalogDb string = sqlCatalogDb.name - -@description('The name of the SQL Ordering portable resource') -output sqlOrderingDb string = sqlOrderingDb.name - -@description('The name of the SQL Webhooks portable resource') -output sqlWebhooksDb string = sqlWebhooksDb.name - -@description('The name of the Redis Keystore portable resource') -output redisKeystore string = redisKeystore.name - -@description('The name of the Redis Basket portable resource') -output redisBasket string = redisBasket.name - -@description('The name of the RabbitMQ portable resource') -output rabbitmq string = rabbitmq.name diff --git a/samples/eshop/iac/infra/links.bicep b/samples/eshop/iac/infra/links.bicep deleted file mode 100644 index a20c8bdd..00000000 --- a/samples/eshop/iac/infra/links.bicep +++ /dev/null @@ -1,52 +0,0 @@ -import radius as rad - -resource sqlIdentityDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' existing = { - name: 'identitydb' -} - -resource sqlCatalogDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' existing = { - name: 'catalogdb' -} - -resource sqlOrderingDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' existing = { - name: 'orderingdb' -} - -resource sqlWebhooksDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' existing = { - name: 'webhooksdb' -} - -resource redisKeystore 'Applications.Datastores/redisCaches@2023-10-01-preview' existing = { - name: 'keystore-data' -} - -resource redisBasket 'Applications.Datastores/redisCaches@2023-10-01-preview' existing = { - name: 'basket-data' -} - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' existing = { - name: 'eshop-event-bus' -} - -// Outputs -------------------------------------------------------------------------- - -@description('The name of the SQL Database for Identity.') -output sqlIdentityDb string = sqlIdentityDb.name - -@description('The name of the SQL Database for Catalog.') -output sqlCatalogDb string = sqlCatalogDb.name - -@description('The name of the SQL Database for Ordering.') -output sqlOrderingDb string = sqlOrderingDb.name - -@description('The name of the SQL Database for Webhooks.') -output sqlWebhooksDb string = sqlWebhooksDb.name - -@description('The name of the Redis Cache for Keystore.') -output redisKeystore string = redisKeystore.name - -@description('The name of the Redis Cache for Basket.') -output redisBasket string = redisBasket.name - -@description('The name of the RabbitMQ Message Queue.') -output rabbitmq string = rabbitmq.name diff --git a/samples/eshop/infra/infra.bicep b/samples/eshop/infra/infra.bicep new file mode 100644 index 00000000..f16d492e --- /dev/null +++ b/samples/eshop/infra/infra.bicep @@ -0,0 +1,116 @@ +import radius as rad + +@description('Radius environment ID') +param environment string + +@description('Radius application ID') +param application string + +@description('Use Azure Service Bus for messaging. Allowed values: "True", "False".') +@allowed([ + 'True' + 'False' +]) +param AZURESERVICEBUSENABLED string + +// Portable Resource -------------------------------------------------------------- + +resource sqlIdentityDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { + name: 'identitydb' + properties: { + application: application + environment: environment + } +} + +resource sqlCatalogDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { + name: 'catalogdb' + properties: { + application: application + environment: environment + } +} + +resource sqlOrderingDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { + name: 'orderingdb' + properties: { + application: application + environment: environment + } +} + +resource sqlWebhooksDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { + name: 'webhooksdb' + properties: { + application: application + environment: environment + } +} + +resource redisKeystore 'Applications.Datastores/redisCaches@2023-10-01-preview' = { + name: 'keystore-data' + properties: { + application: application + environment: environment + } +} + +resource redisBasket 'Applications.Datastores/redisCaches@2023-10-01-preview' = { + name: 'basket-data' + properties: { + application: application + environment: environment + } +} + +resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' = if (AZURESERVICEBUSENABLED == 'False') { + name: 'rabbitmq' + properties: { + application: application + environment: environment + } +} + +resource servicebus 'Applications.Core/extenders@2023-10-01-preview' = if (AZURESERVICEBUSENABLED == 'True') { + name: 'servicebus' + properties: { + application: application + environment: environment + recipe: { + name: 'servicebus' + parameters: { + topicName: 'eshop_event_bus' + subscriptions: ['Basket', 'Catalog', 'Ordering', 'GracePeriod', 'Payment', 'backgroundtasks', 'Ordering.signalrhub', 'Webhooks'] + } + } + } +} + +// Outputs ------------------------------------ + +@description('The name of the SQL Identity portable resource') +output sqlIdentityDb string = sqlIdentityDb.name + +@description('The name of the SQL Catalog portable resource') +output sqlCatalogDb string = sqlCatalogDb.name + +@description('The name of the SQL Ordering portable resource') +output sqlOrderingDb string = sqlOrderingDb.name + +@description('The name of the SQL Webhooks portable resource') +output sqlWebhooksDb string = sqlWebhooksDb.name + +@description('The name of the Redis Keystore portable resource') +output redisKeystore string = redisKeystore.name + +@description('The name of the Redis Basket portable resource') +output redisBasket string = redisBasket.name + +@description('The name of the RabbitMQ portable resource') +output rabbitmq string = rabbitmq.name + +@description('The name of the Service Bus portable resource') +output servicebus string = servicebus.name + +@description('Event Bus connection string') +output eventBusConnectionString string = (AZURESERVICEBUSENABLED == 'True') ? servicebus.secrets('connectionString') : rabbitmq.properties.host diff --git a/samples/eshop/iac/services/networking.bicep b/samples/eshop/infra/networking.bicep similarity index 100% rename from samples/eshop/iac/services/networking.bicep rename to samples/eshop/infra/networking.bicep diff --git a/samples/eshop/iac/services/basket.bicep b/samples/eshop/services/basket.bicep similarity index 73% rename from samples/eshop/iac/services/basket.bicep rename to samples/eshop/services/basket.bicep index 9458be8f..5e84e381 100644 --- a/samples/eshop/iac/services/basket.bicep +++ b/samples/eshop/services/basket.bicep @@ -5,24 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('Container image tag to use for eshop images') -param TAG string - -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string - -@description('Use Azure Service Bus for messaging.') -@allowed([ - 'True' - 'False' -]) -param AZURESERVICEBUSENABLED string +@description('Container registry to pull from, with optional path.') +param imageRegistry string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string +@description('Container image tag to use for eshop images') +param imageTag string @description('The name of the Radius Gateway') param gatewayName string @@ -39,12 +26,16 @@ param basketGrpcName string @description('The name of the Redis Basket portable resource') param redisBasketName string -@description('The name of the RabbitMQ portable resource') -param rabbitmqName string - -@description('The connection string of the Azure Service Bus') +@description('The connection string for the event bus') @secure() -param serviceBusConnectionString string +param eventBusConnectionString string + +@description('Use Azure Service Bus for messaging. Allowed values: "True", "False".') +@allowed([ + 'True' + 'False' +]) +param AZURESERVICEBUSENABLED string // Container ------------------------------------- @@ -54,19 +45,18 @@ resource basket 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/basket.api:${TAG}' + image: '${imageRegistry}/basket.api:${imageTag}' env: { ASPNETCORE_ENVIRONMENT: 'Development' ASPNETCORE_URLS: 'http://0.0.0.0:80' - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY UseLoadTest: 'False' PATH_BASE: '/basket-api' - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' PORT: '80' GRPC_PORT: '81' AzureServiceBusEnabled: AZURESERVICEBUSENABLED ConnectionString: redisBasket.connectionString() - EventBusConnection: (AZURESERVICEBUSENABLED == 'True') ? serviceBusConnectionString : rabbitmq.properties.host + EventBusConnection: eventBusConnectionString identityUrl: identityHttp.properties.url IdentityUrlExternal: '${gateway.properties.url}/${identityHttp.properties.hostname}' } @@ -112,12 +102,8 @@ resource basketGrpc 'Applications.Core/httpRoutes@2023-10-01-preview' existing = name: basketGrpcName } -// Portable Resource ------------------------------------------ +// Portable Resource ----------------------------------------- resource redisBasket 'Applications.Datastores/redisCaches@2023-10-01-preview' existing = { name: redisBasketName } - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' existing = { - name: rabbitmqName -} diff --git a/samples/eshop/iac/services/catalog.bicep b/samples/eshop/services/catalog.bicep similarity index 69% rename from samples/eshop/iac/services/catalog.bicep rename to samples/eshop/services/catalog.bicep index a748fa01..6a5cefb7 100644 --- a/samples/eshop/iac/services/catalog.bicep +++ b/samples/eshop/services/catalog.bicep @@ -5,31 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string - -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string - -@description('Use Azure storage for custom resource images') -@allowed([ - 'True' - 'False' -]) -param AZURESTORAGEENABLED string - -@description('Use Azure Service Bus for messaging') -@allowed([ - 'True' - 'False' -]) -param AZURESERVICEBUSENABLED string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Name of the Gateway') param gatewayName string @@ -40,17 +20,22 @@ param catalogHttpName string @description('The name of the Catalog gRPC Route') param catalogGrpcName string -@description('The name of the RabbitMQ portable resource') -param rabbitmqName string - @description('The name of the Catalog SQL portable resource') param sqlCatalogDbName string -@description('The connection string of the Azure Service Bus') +@description('The connection string for the event bus') @secure() -param serviceBusConnectionString string +param eventBusConnectionString string + +@description('Use Azure Service Bus for messaging. Allowed values: "True", "False".') +@allowed([ + 'True' + 'False' +]) +param AZURESERVICEBUSENABLED string // VARIABLES ----------------------------------------------------------------------------------- + var PICBASEURL = '${gateway.properties.url}/webshoppingapigw/c/api/v1/catalog/items/[0]/pic' // CONTAINERS ------------------------------------------------------------------- @@ -61,20 +46,19 @@ resource catalog 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/catalog.api:${TAG}' + image: '${imageRegistry}/catalog.api:${imageTag}' env: { UseCustomizationData: 'False' PATH_BASE: '/catalog-api' ASPNETCORE_ENVIRONMENT: 'Development' - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' PORT: '80' GRPC_PORT: '81' PicBaseUrl: PICBASEURL - AzureStorageEnabled: AZURESTORAGEENABLED - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY + AzureStorageEnabled: 'False' AzureServiceBusEnabled: AZURESERVICEBUSENABLED ConnectionString: sqlCatalogDb.connectionString() - EventBusConnection: (AZURESERVICEBUSENABLED == 'True') ? serviceBusConnectionString : rabbitmq.properties.host + EventBusConnection: eventBusConnectionString } ports: { http: { @@ -114,7 +98,3 @@ resource catalogGrpc 'Applications.Core/httpRoutes@2023-10-01-preview' existing resource sqlCatalogDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' existing = { name: sqlCatalogDbName } - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' existing = { - name: rabbitmqName -} diff --git a/samples/eshop/iac/services/identity.bicep b/samples/eshop/services/identity.bicep similarity index 91% rename from samples/eshop/iac/services/identity.bicep rename to samples/eshop/services/identity.bicep index bece6369..ecf0bae4 100644 --- a/samples/eshop/iac/services/identity.bicep +++ b/samples/eshop/services/identity.bicep @@ -5,18 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string - -@description('Use dev spaces') -@allowed([ - 'True' - 'False' -]) -param ENABLEDEVSPACES string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Name of the Gateway') param gatewayName string @@ -56,7 +49,7 @@ resource identity 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/identity.api:${TAG}' + image: '${imageRegistry}/identity.api:${imageTag}' env: { PATH_BASE: '/identity-api' ASPNETCORE_ENVIRONMENT: 'Development' @@ -64,9 +57,7 @@ resource identity 'Applications.Core/containers@2023-10-01-preview' = { OrchestratorType: 'K8S' IsClusterEnv: 'True' DPConnectionString: redisKeystore.connectionString() - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY - XamarinCallback: '' - EnableDevspaces: ENABLEDEVSPACES + EnableDevspaces: 'False' ConnectionString: sqlIdentityDb.connectionString() MvcClient: '${gateway.properties.url}/${webmvcHttp.properties.hostname}' SpaClient: gateway.properties.url diff --git a/samples/eshop/iac/services/ordering.bicep b/samples/eshop/services/ordering.bicep similarity index 78% rename from samples/eshop/iac/services/ordering.bicep rename to samples/eshop/services/ordering.bicep index 040fac7e..e4483f7a 100644 --- a/samples/eshop/iac/services/ordering.bicep +++ b/samples/eshop/services/ordering.bicep @@ -5,24 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string - -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string - -@description('Use Azure Service Bus for messaging') -@allowed([ - 'True' - 'False' -]) -param AZURESERVICEBUSENABLED string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Name of the Gateway') param gatewayName string @@ -51,15 +38,19 @@ param orderbgtasksHttpName string @description('Name of the Keystore Redis portable resource') param redisKeystoreName string -@description('The name of the RabbitMQ portable resource') -param rabbitmqName string - @description('Name of the Ordering SQL portable resource') param sqlOrderingDbName string -@description('The connection string of the Azure Service Bus') +@description('The connection string for the event bus') @secure() -param serviceBusConnectionString string +param eventBusConnectionString string + +@description('Use Azure Service Bus for messaging. Allowed values: "True", "False".') +@allowed([ + 'True' + 'False' +]) +param AZURESERVICEBUSENABLED string // CONTAINERS ------------------------------------------------------- @@ -69,15 +60,14 @@ resource ordering 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/ordering.api:${TAG}' + image: '${imageRegistry}/ordering.api:${imageTag}' env: { ASPNETCORE_ENVIRONMENT: 'Development' ASPNETCORE_URLS: 'http://0.0.0.0:80' UseCustomizationData: 'False' AzureServiceBusEnabled: AZURESERVICEBUSENABLED CheckUpdateTime: '30000' - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' UseLoadTest: 'False' 'Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ': 'Verbose' 'Serilog__MinimumLevel__Override__ordering-api': 'Verbose' @@ -85,7 +75,7 @@ resource ordering 'Applications.Core/containers@2023-10-01-preview' = { GRPC_PORT: '81' PORT: '80' ConnectionString: sqlOrderingDb.connectionString() - EventBusConnection: (AZURESERVICEBUSENABLED == 'True') ? serviceBusConnectionString : rabbitmq.properties.host + EventBusConnection: eventBusConnectionString identityUrl: identityHttp.properties.url IdentityUrlExternal: '${gateway.properties.url}/${identityHttp.properties.hostname}' } @@ -119,20 +109,19 @@ resource orderbgtasks 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/ordering.backgroundtasks:${TAG}' + image: '${imageRegistry}/ordering.backgroundtasks:${imageTag}' env: { ASPNETCORE_ENVIRONMENT: 'Development' ASPNETCORE_URLS: 'http://0.0.0.0:80' UseCustomizationData: 'False' CheckUpdateTime: '30000' GracePeriodTime: '1' - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY UseLoadTest: 'False' 'Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ': 'Verbose' - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' AzureServiceBusEnabled: AZURESERVICEBUSENABLED ConnectionString: sqlOrderingDb.connectionString() - EventBusConnection: (AZURESERVICEBUSENABLED == 'True') ? serviceBusConnectionString : rabbitmq.properties.host + EventBusConnection: eventBusConnectionString } ports: { http: { @@ -156,17 +145,16 @@ resource orderingsignalrhub 'Applications.Core/containers@2023-10-01-preview' = properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/ordering.signalrhub:${TAG}' + image: '${imageRegistry}/ordering.signalrhub:${imageTag}' env: { PATH_BASE: '/payment-api' ASPNETCORE_ENVIRONMENT: 'Development' ASPNETCORE_URLS: 'http://0.0.0.0:80' - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY - OrchestratorType: ORCHESTRATOR_TYPE + OrchestratorType: 'K8S' IsClusterEnv: 'True' AzureServiceBusEnabled: AZURESERVICEBUSENABLED - EventBusConnection: (AZURESERVICEBUSENABLED == 'True') ? serviceBusConnectionString : rabbitmq.properties.host - SignalrStoreConnectionString: '${redisKeystore.properties.host}:${redisKeystore.properties.port},password=${redisKeystore.password()},abortConnect=False' + EventBusConnection: eventBusConnectionString + SignalrStoreConnectionString: redisKeystore.connectionString() identityUrl: identityHttp.properties.url IdentityUrlExternal: '${gateway.properties.url}/${identityHttp.properties.hostname}' } @@ -245,7 +233,3 @@ resource redisKeystore 'Applications.Datastores/redisCaches@2023-10-01-preview' resource sqlOrderingDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' existing = { name: sqlOrderingDbName } - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' existing = { - name: rabbitmqName -} diff --git a/samples/eshop/iac/services/payment.bicep b/samples/eshop/services/payment.bicep similarity index 57% rename from samples/eshop/iac/services/payment.bicep rename to samples/eshop/services/payment.bicep index 3fa8a941..7523a461 100644 --- a/samples/eshop/iac/services/payment.bicep +++ b/samples/eshop/services/payment.bicep @@ -5,34 +5,25 @@ import radius as rad @description('Radius application ID') param application string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string - -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string - -@description('Use Azure Service Bus for messaging') -@allowed([ - 'True' - 'False' -]) -param AZURESERVICEBUSENABLED string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Name of the Payment HTTP route') param paymentHttpName string -@description('The name of the RabbitMQ portable resource') -param rabbitmqName string - -@description('The connection string of the Azure Service Bus') +@description('The connection string for the event bus') @secure() -param serviceBusConnectionString string +param eventBusConnectionString string + +@description('Use Azure Service Bus for messaging. Allowed values: "True", "False".') +@allowed([ + 'True' + 'False' +]) +param AZURESERVICEBUSENABLED string // CONTAINERS --------------------------------------------------------- @@ -42,14 +33,13 @@ resource payment 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/payment.api:${TAG}' + image: '${imageRegistry}/payment.api:${imageTag}' env: { - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY 'Serilog__MinimumLevel__Override__payment-api.IntegrationEvents.EventHandling': 'Verbose' 'Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ': 'Verbose' - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' AzureServiceBusEnabled: AZURESERVICEBUSENABLED - EventBusConnection: (AZURESERVICEBUSENABLED == 'True') ? serviceBusConnectionString : rabbitmq.properties.host + EventBusConnection: eventBusConnectionString } ports: { http: { @@ -66,9 +56,3 @@ resource payment 'Applications.Core/containers@2023-10-01-preview' = { resource paymentHttp 'Applications.Core/httpRoutes@2023-10-01-preview' existing = { name: paymentHttpName } - -// PORTABLE RESOURCES ----------------------------------------------------------- - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' existing = { - name: rabbitmqName -} diff --git a/samples/eshop/iac/services/seq.bicep b/samples/eshop/services/seq.bicep similarity index 100% rename from samples/eshop/iac/services/seq.bicep rename to samples/eshop/services/seq.bicep diff --git a/samples/eshop/iac/services/web.bicep b/samples/eshop/services/web.bicep similarity index 89% rename from samples/eshop/iac/services/web.bicep rename to samples/eshop/services/web.bicep index e82bc44e..9717bb3a 100644 --- a/samples/eshop/iac/services/web.bicep +++ b/samples/eshop/services/web.bicep @@ -5,17 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string - -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Name of the Gateway') param gatewayName string @@ -49,14 +43,13 @@ resource webspa 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/webspa:${TAG}' + image: '${imageRegistry}/webspa:${imageTag}' env: { PATH_BASE: '/' ASPNETCORE_ENVIRONMENT: 'Production' ASPNETCORE_URLS: 'http://0.0.0.0:80' UseCustomizationData: 'False' - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' IsClusterEnv: 'True' CallBackUrl: '${gateway.properties.url}/' DPConnectionString: redisKeystore.connectionString() @@ -103,16 +96,15 @@ resource webmvc 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/webmvc:${TAG}' + image: '${imageRegistry}/webmvc:${imageTag}' env: { ASPNETCORE_ENVIRONMENT: 'Development' ASPNETCORE_URLS: 'http://0.0.0.0:80' PATH_BASE: '/webmvc' UseCustomizationData: 'False' DPConnectionString: redisKeystore.connectionString() - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY UseLoadTest: 'False' - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' IsClusterEnv: 'True' ExternalPurchaseUrl: '${gateway.properties.url}/${webshoppingapigwHttp.properties.hostname}' CallBackUrl: '${gateway.properties.url}/webmvc' diff --git a/samples/eshop/iac/services/webhooks.bicep b/samples/eshop/services/webhooks.bicep similarity index 81% rename from samples/eshop/iac/services/webhooks.bicep rename to samples/eshop/services/webhooks.bicep index ec8c3797..6d3a894f 100644 --- a/samples/eshop/iac/services/webhooks.bicep +++ b/samples/eshop/services/webhooks.bicep @@ -5,21 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string - -@description('Use Azure Service Bus for messaging') -@allowed([ - 'True' - 'False' -]) -param AZURESERVICEBUSENABLED string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Name of the Gateway') param gatewayName string @@ -36,12 +26,16 @@ param webhooksclientHttpName string @description('The name of the Webhooks SQL portable resource') param sqlWebhooksDbName string -@description('The name of the RabbitMQ portable resource') -param rabbitmqName string - -@description('The connection string of the Azure Service Bus') +@description('The connection string for the event bus') @secure() -param serviceBusConnectionString string +param eventBusConnectionString string + +@description('Use Azure Service Bus for messaging. Allowed values: "True", "False".') +@allowed([ + 'True' + 'False' +]) +param AZURESERVICEBUSENABLED string // CONTAINERS ----------------------------------------------------------- @@ -51,15 +45,15 @@ resource webhooks 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/webhooks.api:${TAG}' + image: '${imageRegistry}/webhooks.api:${imageTag}' env: { PATH_BASE: '/webhooks-api' ASPNETCORE_ENVIRONMENT: 'Development' ASPNETCORE_URLS: 'http://0.0.0.0:80' - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' AzureServiceBusEnabled: AZURESERVICEBUSENABLED ConnectionString: sqlWebhooksDb.connectionString() - EventBusConnection: (AZURESERVICEBUSENABLED == 'True') ? serviceBusConnectionString : rabbitmq.properties.host + EventBusConnection: eventBusConnectionString identityUrl: identityHttp.properties.url IdentityUrlExternal: '${gateway.properties.url}/${identityHttp.properties.hostname}' } @@ -90,7 +84,7 @@ resource webhooksclient 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/webhooks.client:${TAG}' + image: '${imageRegistry}/webhooks.client:${imageTag}' env: { ASPNETCORE_ENVIRONMENT: 'Production' ASPNETCORE_URLS: 'http://0.0.0.0:80' @@ -142,7 +136,3 @@ resource webhooksclientHttp 'Applications.Core/httpRoutes@2023-10-01-preview' ex resource sqlWebhooksDb 'Applications.Datastores/sqlDatabases@2023-10-01-preview' existing = { name: sqlWebhooksDbName } - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' existing = { - name: rabbitmqName -} diff --git a/samples/eshop/iac/services/webshopping.bicep b/samples/eshop/services/webshopping.bicep similarity index 87% rename from samples/eshop/iac/services/webshopping.bicep rename to samples/eshop/services/webshopping.bicep index a30ac769..143edd08 100644 --- a/samples/eshop/iac/services/webshopping.bicep +++ b/samples/eshop/services/webshopping.bicep @@ -5,14 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Name of the Gateway') param gatewayName string @@ -50,21 +47,18 @@ param webshoppingapigwHttp2Name string @description('Web Shopping Aggregator Http Route name') param webshoppingaggHttpName string -@description('The name of the RabbitMQ portable resource') -param rabbitmqName string - // Based on https://github.com/dotnet-architecture/eShopOnContainers/tree/dev/deploy/k8s/helm/webshoppingagg resource webshoppingagg 'Applications.Core/containers@2023-10-01-preview' = { name: 'webshoppingagg' properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/webshoppingagg:${TAG}' + image: '${imageRegistry}/webshoppingagg:${imageTag}' env: { ASPNETCORE_ENVIRONMENT: 'Development' PATH_BASE: '/webshoppingagg' ASPNETCORE_URLS: 'http://0.0.0.0:80' - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' IsClusterEnv: 'True' urls__basket: basketHttp.properties.url urls__catalog: catalogHttp.properties.url @@ -88,10 +82,6 @@ resource webshoppingagg 'Applications.Core/containers@2023-10-01-preview' = { } } connections: { - rabbitmq: { - source: rabbitmq.id - disableDefaultEnvVars: true - } identity: { source: identityHttp.id disableDefaultEnvVars: true @@ -119,7 +109,7 @@ resource webshoppingapigw 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/envoy:latest' + image: '${imageRegistry}/envoy:latest' ports: { http: { containerPort: 80 @@ -183,9 +173,3 @@ resource webshoppingapigwHttp 'Applications.Core/httpRoutes@2023-10-01-preview' resource webshoppingapigwHttp2 'Applications.Core/httpRoutes@2023-10-01-preview' existing = { name: webshoppingapigwHttp2Name } - -// PORTABLE RESOURCES -------------------------------------------------------- - -resource rabbitmq 'Applications.Messaging/rabbitMQQueues@2023-10-01-preview' existing = { - name: rabbitmqName -} diff --git a/samples/eshop/iac/services/webstatus.bicep b/samples/eshop/services/webstatus.bicep similarity index 92% rename from samples/eshop/iac/services/webstatus.bicep rename to samples/eshop/services/webstatus.bicep index ea5bac82..2b230f04 100644 --- a/samples/eshop/iac/services/webstatus.bicep +++ b/samples/eshop/services/webstatus.bicep @@ -5,17 +5,11 @@ import radius as rad @description('Radius application ID') param application string -@description('What container orchestrator to use') -@allowed([ - 'K8S' -]) -param ORCHESTRATOR_TYPE string - -@description('Optional App Insights Key') -param APPLICATION_INSIGHTS_KEY string +@description('Container registry to pull from, with optional path.') +param imageRegistry string @description('Container image tag to use for eshop images') -param TAG string +param imageTag string @description('Basket Http Route name') param basketHttpName string @@ -58,7 +52,7 @@ resource webstatus 'Applications.Core/containers@2023-10-01-preview' = { properties: { application: application container: { - image: 'ghcr.io/radius-project/samples/eshop/webstatus:${TAG}' + image: '${imageRegistry}/webstatus:${imageTag}' env: { ASPNETCORE_ENVIRONMENT: 'Development' ASPNETCORE_URLS: 'http://0.0.0.0:80' @@ -82,8 +76,7 @@ resource webstatus 'Applications.Core/containers@2023-10-01-preview' = { HealthChecksUI__HealthChecks__9__Uri: '${orderingsignalrhubHttp.properties.url}/hc' HealthChecksUI__HealthChecks__10__Name: 'Ordering HTTP Background Check' HealthChecksUI__HealthChecks__10__Uri: '${orderbgtasksHttp.properties.url}/hc' - ApplicationInsights__InstrumentationKey: APPLICATION_INSIGHTS_KEY - OrchestratorType: ORCHESTRATOR_TYPE + ORCHESTRATOR_TYPE: 'K8S' } ports: { http: { diff --git a/samples/eshop/src/README.md b/samples/eshop/src/README.md new file mode 100644 index 00000000..83dfb523 --- /dev/null +++ b/samples/eshop/src/README.md @@ -0,0 +1,3 @@ +# eShopOnContainers Source Code + +The eShopOnContainers source code is available [here](https://github.com/dotnet-architecture/eShopOnContainers). diff --git a/samples/eshop/envoy/Dockerfile b/samples/eshop/src/envoy/Dockerfile similarity index 100% rename from samples/eshop/envoy/Dockerfile rename to samples/eshop/src/envoy/Dockerfile diff --git a/samples/eshop/envoy/README.md b/samples/eshop/src/envoy/README.md similarity index 100% rename from samples/eshop/envoy/README.md rename to samples/eshop/src/envoy/README.md diff --git a/samples/eshop/envoy/envoy.yaml b/samples/eshop/src/envoy/envoy.yaml similarity index 100% rename from samples/eshop/envoy/envoy.yaml rename to samples/eshop/src/envoy/envoy.yaml