{"id":19099884,"url":"https://github.com/microsoft/RockPaperScissorsLizardSpock","last_synced_at":"2025-04-18T17:32:19.402Z","repository":{"id":35885889,"uuid":"215887994","full_name":"microsoft/RockPaperScissorsLizardSpock","owner":"microsoft","description":"Rock, Paper, Scissors, Lizard, Spock - Sample Application","archived":true,"fork":false,"pushed_at":"2023-03-04T09:38:28.000Z","size":47183,"stargazers_count":590,"open_issues_count":8,"forks_count":289,"subscribers_count":37,"default_branch":"main","last_synced_at":"2024-10-01T07:21:19.428Z","etag":null,"topics":["aspnetcore","azure","azure-functions","azure-kubernetes-service","blazor","dotnet-core","java","javascript","nodejs","php","python","tensorflow"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null}},"created_at":"2019-10-17T21:23:23.000Z","updated_at":"2024-09-17T16:59:15.000Z","dependencies_parsed_at":"2023-02-15T11:45:55.073Z","dependency_job_id":null,"html_url":"https://github.com/microsoft/RockPaperScissorsLizardSpock","commit_stats":null,"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FRockPaperScissorsLizardSpock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FRockPaperScissorsLizardSpock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FRockPaperScissorsLizardSpock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FRockPaperScissorsLizardSpock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microsoft","download_url":"https://codeload.github.com/microsoft/RockPaperScissorsLizardSpock/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223783108,"owners_count":17201903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnetcore","azure","azure-functions","azure-kubernetes-service","blazor","dotnet-core","java","javascript","nodejs","php","python","tensorflow"],"created_at":"2024-11-09T03:52:21.025Z","updated_at":"2025-04-18T17:32:19.396Z","avatar_url":"https://github.com/microsoft.png","language":"C#","readme":"---\r\npage_type: sample\r\nname: \"Rock, Paper, Scissors, Lizard, Spock\"\r\nurlFragment: azure-rock-paper-scissors\r\ndescription: \"Rock, Paper, Scissors, Lizard, Spock is the geek version of the classic Rock, Paper, Scissors game.\"\r\nlanguages:\r\n- csharp\r\n- powershell\r\n- html\r\n- php\r\n- python\r\n- javascript\r\n- java\r\nproducts:\r\n- azure-cosmos-db\r\n- azure-kubernetes-service\r\n- dotnet-core\r\n- azure-cognitive-services\r\n- vs\r\n- vs-code\r\n---\r\n\r\n# Rock, Paper, Scissors, Lizard, Spock - Sample Application\r\n\r\nWe are happy to announce the release of Rock, Paper, Scissors, Lizard, Spock sample application running in Azure presented at [Microsoft Ignite 2019](https://aka.ms/DevKeynote) by [Scott Hanselman](https://www.hanselman.com) and friends. \r\n\r\n![](Documents/Images/RPSLS-Title.png)\r\n\r\nRock, Paper, Scissors, Lizard, Spock is the geek version of the classic Rock, Paper, Scissors game. Rock, Paper, Scissors, Lizard, Spock is created by [Sam Kass and Karen Bryla.](http://www.samkass.com/theories/RPSSL.html)\r\n\r\nThe Rock, Paper, Scissors, Lizard, Spock - Sample Application shows a multilanguage application built with Visual Studio and Visual Studio Code, deployed with GitHub Actions and running on Azure Kubernetes Service (AKS). The sample application also uses Machine Learning and Azure Cognitive Services (Custom Vision API). Languages used in this application include .NET, Node.js, Python, Java, and PHP.\r\n\r\n- Missed the keynote session? [Watch it here](https://aka.ms/devkeynote).\r\n\r\n[![Application development for everyone](Documents/Images/ScottHa-Keynote.png)](https://aka.ms/devkeynote)\r\n\r\n![](Documents/Images/RPSLS.gif)\r\n\r\n- Get everything that you need to deploy the code and run in your subscription.\r\n\r\n# Table of contents\r\n\r\n- [Application Screens](#screens)\r\n- [Application Diagram](#diagram)  \r\n- [Getting Started](#getting-started) \r\n- [Deployment scenarios](#deployment-scenarios)\r\n  - [Deploy RPSLS using one script](#deploy-unified)\r\n  - [Deploy RPSLS step by step](#deploy-resources)\r\n- [Swag](#Swag)\r\n- [Feedback](#feedback)\r\n- [Contributing](#contributing)\r\n\r\n# \u003ca name=\"screens\"\u003e\u003c/a\u003eApplication Screens\r\n\r\n![](Documents/Images/screen-choose-your-opponent.png)\r\n![](Documents/Images/screen-battle.png)\r\n![](Documents/Images/screen-result.png)\r\n\r\n# \u003ca name=\"diagram\"\u003e\u003c/a\u003eApplication Diagram\r\n\r\n![](Documents/Images/RPSLS-Diagram.png)\r\n\r\nThis a multilanguage application running on AKS with AI embedded. There are 5 bots (.NET, NodeJS, Python, Java and PHP) the user can select a language as the opponent and both, the user and the bot will have to select an object to play. The Game Manager which is a .NET API decides who wins based on the logic of the game. If the user is authenticated using Twitter the bots will call a predictor AI Model (Python Azure Function), this model learns from the selections of the objects that the user have done based on the history (stored in a Cosmos DB) to try to predict their next move. If the user is not authenticated the bots will select a random object. There is also a TensorFlow model created with Custom Vision to allow the user to play with their hands by using the webcam.\r\n\r\n# \u003ca name=\"getting-started\"\u003e\u003c/a\u003eGetting Started\r\n\r\n## Pre-Requisites\r\n\r\n1. You will need [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) on Windows 10.\r\n1. You will need [Docker Desktop](https://www.docker.com/products/docker-desktop).\r\n\r\nIf you want to deploy this solution in Azure:\r\n\r\n1. You will need and Azure Subscription in order to deploy this.\r\n1. Azure CLI.\r\n1. Download and install helm.\r\n\r\n## New to Microsoft Azure?\r\n\r\nYou will need an Azure subscription to work with this demo code. You can:\r\n\r\n- Open an account for free [Azure subscription](https://azure.microsoft.com/free/). You get credits that can be used to try out paid Azure services. Even after the credits are used up, you can keep the account and use free Azure services and features, such as the Web Apps feature in Azure App Service.\r\n- [Activate Visual Studio subscriber benefits](https://azure.microsoft.com/pricing/member-offers/credit-for-visual-studio-subscribers/). Your Visual Studio subscription gives you credits every month that you can use for paid Azure services.\r\n- Create an [Azure Student Account](https://azure.microsoft.com/free/students/) and get free credit when you create your account.\r\n\r\nLearn more about it with [Microsoft Learn - Introduction to Azure](https://docs.microsoft.com/learn/azure).\r\n\r\n\r\n# \u003ca name=\"deployment-scenarios\"\u003e\u003c/a\u003eDeploy to Azure\r\n\r\nYou can either go through all steps and customizing its configuration or run one single command.\r\n\r\n## \u003ca name=\"deploy-unified\"\u003e\u003c/a\u003eDeploy RPSLS using one script\r\n\r\nExecute the script located in Deploy folder with the following parameters:\r\n```\r\n.\\Deploy-Unified.ps1 -resourceGroup \u003cresource-group-name\u003e -location \u003clocation\u003e -clientId \u003cservice-principal-id\u003e -password \u003cservice-principal-password\u003e -subscription \u003csubscription-id\u003e\r\n```\r\n\r\n- `resourceGroup`: The name of your resource group where all infrastructure will be created `Required`\r\n- `location`: Select where you want to create your resource group, for example: `eastus` `Required`\r\n- `clientId`: Id of the service principal used to create the AKS `Optional`\r\n- `password`: Password of the service principal `Optional`\r\n- `subscription`: Id of your subscription where you are going to deploy your resource group `Required`\r\n\r\nIf service principal credentials are not passed a new one will be created.\r\n\r\n## \u003ca name=\"deploy-resources\"\u003e\u003c/a\u003eDeploy RPSLS step by step\r\n\r\nTo run RPSLS you need to create the Azure infrastructure. There are two ways to do it. Using Azure portal or using a Powershell script.\r\n\r\n### \u003ca name=\"create-infrastructure-portal\"\u003e\u003c/a\u003eStep 1 - Option 1: Creating infrastructure using Azure Portal\r\n\r\nAn ARM template is provided so you can create the whole infrastructure required for RPSLS\r\n\r\n[![Deploy to Azure](Documents/Images/deploy-to-azure.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FRockPaperScissorsLizardSpock%2Fmain%2FDeploy%2Farm%2Fdeployment.json)\r\n\r\n- `servicePrincipalId`: Id of the service principal used to create the AKS `Required`\r\n- `servicePrincipalSecret`: Password of the service principal `Required`\r\n- `aksVersion`: AKS version to use. `Required`\r\n\r\nThe deployment could take more than 10 minutes, and once finished all needed resources will be created.\r\n\r\n### \u003ca name=\"create-infrastructure-cli\"\u003e\u003c/a\u003eStep 1 - Option 2: Create the resources using the CLI\r\n\r\nYou can use the CLI to deploy the ARM script. Open a Powershell window from the `/Deploy` folder and run the `Deploy-Arm-Azure.ps1` with following parameters:\r\n\r\n- `-resourceGroup`: Name of the resource group `Required`\r\n- `-location`: Location of the resource group `Required if resourceGroup does not exist`\r\n- `-clientId`: Id of the service principal used to create the AKS `Optional`\r\n- `-password`: Password of the service principal `Optional`\r\n\r\nIf service principal credentials are not passed a new one will be created.\r\n\r\nOnce script finishes, everything is installed. If a service principal has been created, the script will output the service principal details - _please, take note of the appId and password properties for use them in the AKS deployment_\r\n\r\n### \u003ca name=\"deploy-aks\"\u003e\u003c/a\u003eStep 2: Deploy RPSLS on AKS\r\n\r\nPre-requisites for this deployment are to have:\r\n\r\n- The AKS and all related resources deployed in Azure\r\n- A terminal with Powershell environment\r\n- [Azure CLI 2.0](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) installed.\r\n- [Azure Functions Core Tools](https://docs.microsoft.com/es-es/azure/azure-functions/functions-run-local) installed (required only to deploy Predictor).\r\n- [Kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) installed with the last version (v1.16.0 at this moment).\r\n- [Helm 3](https://helm.sh/docs/intro/install/) installed with 3.0 or superior version (v3.0.0 at this moment).\r\n- Docker installed\r\n\r\n#### Service Principal\r\n\r\nA Service Principal is needed for creating the AKS. If you use the [CLI for create the resources](#create-infrastructure-cli). You need the client id and password of a Service Principal to install RPSLS.\r\n\r\nIn case you use [Azure Portal for the resources' creation](#create-infrastructure-portal), you can also reuse a SP or create manually a new one for passing the credentials to the template.\r\n\r\n#### Connecting kubectl to AKS\r\n\r\nFrom the terminal type:\r\n\r\n- `az login` and follow instructions to log into your Azure.\r\n- If you have more than one subscription type `az account list -o table` to list all your Azure subscriptions. Then type `az account set --subscription \u003csubscription-id\u003e` to select your subscription\r\n- `az aks get-credentials -n \u003cyour-aks-name\u003e -g \u003cresource-group-name\u003e` to download the configuration files that `kubectl` needs to connect to your AKS.\r\n\r\nAt this point if you type `kubectl config current-context` the name of your AKS cluster should be displayed. That means that `kubectl` is ready to use your AKS\r\n\r\n### Installing FlexVolume\r\n\r\nThe KeyVault support is implemented through [FlexVol](https://github.com/Azure/kubernetes-keyvault-flexvol). To install Flex Volume in the AKS, type the following:\r\n\r\n```\r\n.\\Create-Kv-FlexVolume.ps1\r\n```\r\n#### Publish Python Azure Function\r\n\r\nTo publish the Azure Function you can execute the next command of the Azure Functions Core Tools from the folder `/Source/Functions/RPSLS.Python.Api`:\r\n```\r\nfunc azure functionapp publish \u003cfuncapp-name\u003e --no-build\r\n```\r\nThe value for `funcapp-name` must be the name of the Function App created in your Azure Resource Group.\r\n\r\n#### Configuring services\r\n\r\nBefore deploying services using Helm, you need to setup the configuration. We refer to the configuration file with the name of _gvalues_ file. This file **contains all secrets** so beware to not commit in your repo accidentally.\r\n\r\nA template of this file is in `powershell/gvalues.template`. The deployment scripts use this file by default, **but do not rely on editing this file**. Instead create a copy of it a folder outside the repository and use the `-valuesFile` parameter of the deployment script.\r\n\r\n\u003e **Note:** The folder `/Deploy/helm/__values/` is added to `.gitignore`, so you can keep all your configuration files in it, to avoid accidental pushes.\r\n\r\nPlease refer to the comments of the file for its usage.\r\n\r\n##### Auto generating the configuration file\r\n\r\nGenerating a valid _gvalues_ file can be a bit harder, so there is a Powershell script that can do all work by you. This script assumes that all resources are deployed in the same resource group, and this resource group contains only the RPSLS resources. Also assumes the Azure resources have been created using the **tools provided in this repo**.\r\n\r\n\u003e **Note** The Generate-Config.ps1 uses the _application-insights_ CLI extension to find the application insights id. Install it with `az extension add --name application-insights`\r\n\r\n\u003e **Note** The configuration script requires the Azure function key so internal aks services can call it. So before executing the Generate-Config.ps1 make sure that the function is already published and the function key exists. \r\n\r\nTo auto-generate your _gvalues_ file just go to `/Deploy/powershell` folder and from a Powershell window, type the following:\r\n\r\n```\r\n.\\Generate-Config.ps1 -resourceGroup \u003cyour-resource-group\u003e -outputFile ..\\helm\\__values\\\u003cname-of-your-file\u003e\r\n```\r\n\r\nThe `Generate-Config.ps1` script accepts so many parameters. [Here](./Deploy/powershell/readme.md#Generate-Config) you can find a list of them all.\r\n\r\nThe script checks that all needed resources exists in the resource group. If some resource is missing or there is an unexpected resource, the script exits.\r\n\r\n#### Build \u0026 deploy images to ACR\r\n\r\nYou can **manually use docker-compose** to build and push the images to the ACR. If using compose you can set following environment variables:\r\n\r\n- `TAG`: Will contain the generated docker images tag\r\n- `REGISTRY`: Registry to use. This variable should be set to the login server of the ACR\r\n\r\nOnce set, you can use `docker-compose build` and `docker-compose push` to build and push the images.\r\n\r\nAdditionally there is a Powershell script in the `Deploy` folder, named `Build-Push.ps1`. You can use this script for building and pushing ALL images to ACR. Parameters of this script are:\r\n\r\n- `resourceGroup`: Resource group where ACR is. **Required**.\r\n- `acrName`: ACR name (not login server). **Required**.\r\n- `dockerTag`: Tag to use for generated images (defaults to `latest`)\r\n- `dockerBuild`: If `$true` (default value) docker images will be built using `docker-compose build`.\r\n- `dockerPush`: If `$true` (default value) docker images will be push to ACR using `docker-compose push`.\r\n\r\nThis script uses `az` CLI to get ACR information, and then uses `docker-compose` to build and push the images to ACR.\r\n\r\nTo build and push images tagged with v1 to a ACR named my-acr in resource group named my-rg, execute the following command inside `/Deploy/powershell`\r\n\r\n```\r\n.\\Build-Push.ps1 -resourceGroup my-rg -dockerTag v1 -acrName my-acr\r\n```\r\n\r\nTo just push the images (without building them before):\r\n\r\n```\r\n.\\Build-Push.ps1 -resourceGroup my-rg -dockerTag v1 -acrName my-acr -dockerBuild $false\r\n```\r\n\r\n#### Deploying services\r\n\r\nYou need to use Powershell and run `./Deploy-Images-Aks.ps1`. A typical call is:\r\n\r\n```ps\r\n.\\Deploy-Images-Aks.ps1 -resourceGroup $resourceGroup -aksName $myAks -acrName $myAcr -valuesFile $myValuesFilePath -tag v1\r\n```\r\n\r\n**Note**: Read the [documentation of this script](./Deploy/powershell/readme.md) for a list of all parameters.\r\n\r\nThis script will install all services using Helm and your custom configuration from the configuration file set by `-valuesFile` parameter.\r\n\r\nThe parameter `charts` allow for a selective installation of charts. Is a list of comma-separated values that mandates the services to deploy in the AKS. Values are:\r\n\r\n- `cs` C# Player.\r\n- `nj` NodeJS Player.\r\n- `py` Python Player.\r\n- `php` PHP Player.\r\n- `jv` Java Player.\r\n- `web` Website\r\n- `gm` Game Manager\r\n\r\n# Swag\r\n\r\nWe distributed some swag after the keynote session at Ignite (t-shirts, stickers and pins) but we had a limited amount so it made sense to open up the logo for swag.\r\n\r\n\u003ca href=\"Documents/Swag/logo.png\"\u003e\u003cbr/\u003e\u003cimg src=\"Documents/Swag/logo.png\" width=\"250px\"/\u003e\u003c/a\u003e\r\n\r\n# Feedback\r\n\r\n[Help us improve this sample application with your valuable feedback by filling up this survey.](https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbRyg-YAZ0zypKmtaBgQnPt0tUNElFSkhLUFhZUzJEQzdPWUFLR0Y1R1VWTCQlQCN0PWcu)\r\n\r\n[![](Documents/Images/Feedback.png)](https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbRyg-YAZ0zypKmtaBgQnPt0tUNElFSkhLUFhZUzJEQzdPWUFLR0Y1R1VWTCQlQCN0PWcu)\r\n\r\n[If you prefer you can also send us an email with your feedback](mailto:f99f7b8d.microsoft.com@amer.teams.ms).\r\n\r\n# \u003ca name=\"contributing\"\u003e\u003c/a\u003eContributing\r\n\r\nThis project welcomes contributions and suggestions. Most contributions require you to agree to a\r\nContributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us\r\nthe rights to use your contribution. For details, visit https://cla.microsoft.com.\r\n\r\nWhen you submit a pull request, a CLA-bot will automatically determine whether you need to provide\r\na CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions\r\nprovided by the bot. You will only need to do this once across all repos using our CLA.\r\n\r\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\r\nFor more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or\r\ncontact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\r\n","funding_links":[],"categories":["azure","tensorflow"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2FRockPaperScissorsLizardSpock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrosoft%2FRockPaperScissorsLizardSpock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2FRockPaperScissorsLizardSpock/lists"}