Skip to content

Commit

Permalink
Deployed
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduard Keilholz committed Jan 16, 2024
1 parent 31c8747 commit 708a2d4
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 2 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Whack-A-Mole Intagration

on:
push:
branches: [main]

permissions:
id-token: write
contents: read

jobs:
versionize:
runs-on: ubuntu-latest
outputs:
semver: ${{ steps.gitversion.outputs.SemVer }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install GitVersion
uses: gittools/actions/gitversion/[email protected]
with:
versionSpec: "5.x"
- name: Determine Version
id: gitversion
uses: gittools/actions/gitversion/[email protected]
with:
useConfigFile: true

publish-bicep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build & Push
working-directory: infrastructure
run: |
bicep build-params test.main.bicepparam
az bicep build --file main.bicep
- name: Publish Artifact
uses: actions/upload-artifact@v3
with:
name: bicep-templates
path: infrastructure/*.json

infrastructure-incremental:
needs: [publish-bicep, versionize]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Download Artifact
uses: actions/download-artifact@v3
with:
name: bicep-templates
path: ./infrastructure
- name: Az CLI login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy Infrastructure
id: arm
uses: Azure/cli@v1
with:
inlineScript: az deployment sub create --name wam-integration-northeur --location northeurope --template-file ./infrastructure/main.json --parameters ./infrastructure/test.main.json
20 changes: 20 additions & 0 deletions GitVersion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
assembly-versioning-scheme: MajorMinorPatch
assembly-file-versioning-scheme: MajorMinorPatchTag
assembly-informational-format: "{InformationalVersion}"
mode: Mainline
tag-prefix: "[vV]"
continuous-delivery-fallback-tag: ci
major-version-bump-message: '\+semver:\s?(breaking|major)'
minor-version-bump-message: '\+semver:\s?(feature|minor)'
patch-version-bump-message: '\+semver:\s?(fix|patch)'
no-bump-message: '\+semver:\s?(none|skip)'
legacy-semver-padding: 4
build-metadata-padding: 4
commits-since-version-source-padding: 4
commit-message-incrementing: Enabled
branches: {}
ignore:
sha: []
increment: Inherit
commit-date-format: yyyy-MM-dd
merge-message-formats: {}
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
# whack-a-mole-integration
Whack-A-Mole Integration Project
# Whack-A-Mole Game

This is the Whack-A-Mole game, a completely over-engineered game to demonstrate microservices, containers, Azure Container Apps, and real-time communication. This project is managed at GitHub [GitHub Project Page](https://github.com/users/nikneem/projects/3), which is a private project that you need to have granted access for.

## Project structure

There are a couple of repo's involved for this project. This repo, the integration repo, deploys the central cloud environment that all other repo's take advantage of. In essense, it deploys a distributed cache, Container Apps Environment, Logging and intrumentation with Log Analytics & Application Insights, Web PubSub for real-time communication.

### Proxy service

The proxy service is going to be a low weight simple reverse proxy (YARP) to accept external traffic and redirect that to the appropriate service. The repository [can be found here](https://github.com/4DotNet/whack-a-mole-proxy)

### Users service

One service is responsible for creating and resolving users. There is not complicated identity management involved. Once a user registers, he will be assigned a GUID that is stored in the localstore of the browser. This GUID is now used to identify individuals. Once people get to know other people's GUID's they can impersonate other, we take that risk for now as it is only a game. The [Users Service Repository](https://github.com/nikneem/whack-a-mole-games-api) contains all the API Code.

### Game service

One service is responsible for creating games and allowing users to join a game (they become a player in this domain). There can be one game at a time in the new state. In this state, the game allows new players to join (up to x players at a time). The game then advances to active, started, and finished. When a game advances in state, we can create a new game allowing new players to already join the new game, while the previous game is still being played. There is also a cancelled state, allowing us to cancel the game at all times. Reading game information is allowed for everyone (anonymous access), while controlling game state and creating a new game can only be done by 4Dotnet workers (they must log in with their 4Dotnet account). [Repo is here](https://github.com/4DotNet/whack-a-mole-games)

### Vouchers service

The game can be configured to demand voucher codes upon joining a game. This vouchers service verifies wether a voucher is valid (or not), and invalidates vouchers after usage. [Repo is here](https://github.com/4DotNet/whack-a-mole-vouchers)

### Scores service

The scores service receives all the scores done by players. The scores services will be hammered upon when a game has started because each and every time a player whacks a mole, the response time in milliseconds is passed to the server as a request. With a [repo here](https://github.com/4DotNet/whack-a-mole-scores)

### Central dashboard

A central dashboard allows us to show the current game statistics, with a leader board and real-time incoming scores on the left-hand side. On the right-hand side, the dashboard shows the ability to join the new game scheduled for the next round.
25 changes: 25 additions & 0 deletions infrastructure/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
targetScope = 'subscription'

@allowed([ 'tst', 'prd' ])
param runtimeEnvironment string
param appBuildersGroup string

param location string = deployment().location

var defaultResourceName = 'wam-${runtimeEnvironment}-int'
var resourceGroupName = '${defaultResourceName}-rg'

resource resourceGroup 'Microsoft.Resources/resourceGroups@2018-05-01' = {
name: resourceGroupName
location: location
}

module resources 'resources.bicep' = {
name: 'resources'
scope: resourceGroup
params: {
appBuildersGroup: appBuildersGroup
location: location
defaultResourceName: defaultResourceName
}
}
142 changes: 142 additions & 0 deletions infrastructure/resources.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
param appBuildersGroup string

param location string = resourceGroup().location
param defaultResourceName string

var tables = [
'users'
'games'
'scores'
]

resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: '${defaultResourceName}-log'
location: location
properties: {
retentionInDays: 30
sku: {
name: 'PerGB2018'
}
}
}

resource webPubSub 'Microsoft.SignalRService/webPubSub@2023-08-01-preview' = {
name: '${defaultResourceName}-wps'
location: location
sku: {
name: 'Free_F1'
tier: 'Free'
}
kind: 'WebPubSub'
properties: {}
}

resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: '${defaultResourceName}-ai'
location: location
kind: 'web'
properties: {
Application_Type: 'web'
IngestionMode: 'LogAnalytics'
WorkspaceResourceId: logAnalytics.id
}
}

resource redisCache 'Microsoft.Cache/redis@2023-08-01' = {
name: '${defaultResourceName}-cache'
location: location
properties: {
sku: {
name: 'Basic'
family: 'C'
capacity: 0
}
enableNonSslPort: false
publicNetworkAccess: 'Enabled'
}
}

resource appConfiguration 'Microsoft.AppConfiguration/configurationStores@2023-03-01' = {
name: '${defaultResourceName}-appcfg'
location: location
sku: {
name: 'Free'
}
properties: {
publicNetworkAccess: 'Enabled'
}
resource appInsightsConnectionStringConfiguration 'keyValues@2023-03-01' = {
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
properties: {
contentType: 'text/plain'
value: applicationInsights.properties.ConnectionString
}
}
resource redisCacheEndpointConfiguration 'keyValues@2023-03-01' = {
name: 'Cache:Endpoint'
properties: {
contentType: 'text/plain'
value: redisCache.properties.hostName
}
}
resource redisCacheKeyConfiguration 'keyValues@2023-03-01' = {
name: 'Cache:Secret'
properties: {
contentType: 'text/plain'
value: redisCache.listKeys().primaryKey
}
}
}

resource appConfigurationDataReaderRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' = {
name: ' 516239f1-63e1-4d78-a4de-a74fb236a071'
}
module appConfigurationDataReaderRoleAssignment 'roleAssignment.bicep' = {
name: 'appConfigurationDataReaderRoleAssignment'
params: {
principalId: appBuildersGroup
roleDefinitionId: appConfigurationDataReaderRoleDefinition.id
principalType: 'Group'
}
}

// resource storageTableDataContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-05-01-preview' existing = {
// name: '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'
// }
// module storageTableDataContributorRoleAssignment 'roleAssignment.bicep' = {
// name: 'storageTableDataContributorRoleAssignment'
// params: {
// principalId: webApp.identity.principalId
// roleDefinitionId: storageTableDataContributorRoleDefinition.id
// principalType: 'ServicePrincipal'
// }
// }
// module storageTableDataContributorRoleAssignmentToEduard 'roleAssignment.bicep' = {
// name: 'storageTableDataContributorRoleAssignmentToEduard'
// params: {
// principalId: appBuildersGroup
// roleDefinitionId: storageTableDataContributorRoleDefinition.id
// principalType: 'Group'
// }
// }

// resource webPubSubServiceOwnerRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-05-01-preview' existing = {
// name: '12cf5a90-567b-43ae-8102-96cf46c7d9b4'
// }

// module webPubSubContributorRoleAssignment 'roleAssignment.bicep' = {
// name: 'webPubSubContributorRoleAssignment'
// params: {
// principalId: webApp.identity.principalId
// roleDefinitionId: webPubSubServiceOwnerRoleDefinition.id
// principalType: 'ServicePrincipal'
// }
// }
// module webPubSubContributorRoleAssignmentToEduard 'roleAssignment.bicep' = {
// name: 'webPubSubContributorRoleAssignmentToEduard'
// params: {
// principalId: appBuildersGroup
// roleDefinitionId: webPubSubServiceOwnerRoleDefinition.id
// principalType: 'Group'
// }
// }
19 changes: 19 additions & 0 deletions infrastructure/roleAssignment.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
param principalId string
param roleDefinitionId string
@allowed([
'ServicePrincipal'
'ForeignGroup'
'Group'
'Device'
'User'
])
param principalType string = 'ServicePrincipal'

resource allowConfigurationDataReader 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid('${principalId}-${roleDefinitionId}')
properties: {
principalId: principalId
principalType: principalType
roleDefinitionId: roleDefinitionId
}
}
4 changes: 4 additions & 0 deletions infrastructure/test.main.bicepparam
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using './main.bicep'

param runtimeEnvironment = 'tst'
param appBuildersGroup = '0855534d-094e-40e7-9e19-d189578f69a9'

0 comments on commit 708a2d4

Please sign in to comment.