{"id":15710416,"url":"https://github.com/aws/aws-ops-wheel","last_synced_at":"2025-04-06T07:13:45.628Z","repository":{"id":39849795,"uuid":"110152936","full_name":"aws/aws-ops-wheel","owner":"aws","description":"The AWS Ops Wheel is a randomizer that biases for options that haven’t come up recently; you can also outright cheat and specify the next result to be generated.","archived":false,"fork":false,"pushed_at":"2025-02-21T20:28:02.000Z","size":3695,"stargazers_count":336,"open_issues_count":8,"forks_count":66,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-03-30T06:06:47.637Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aws.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"COPYING","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-09T18:43:01.000Z","updated_at":"2025-02-20T14:51:38.000Z","dependencies_parsed_at":"2024-02-07T22:24:08.381Z","dependency_job_id":"fe551b07-39af-4034-88d8-f590a021ff35","html_url":"https://github.com/aws/aws-ops-wheel","commit_stats":{"total_commits":98,"total_committers":26,"mean_commits":3.769230769230769,"dds":0.5816326530612245,"last_synced_commit":"a05d1a885b29a21d22103bdc6a0af2f1f19db0c6"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-ops-wheel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-ops-wheel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-ops-wheel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-ops-wheel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aws","download_url":"https://codeload.github.com/aws/aws-ops-wheel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445671,"owners_count":20939958,"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":[],"created_at":"2024-10-03T21:07:20.508Z","updated_at":"2025-04-06T07:13:45.609Z","avatar_url":"https://github.com/aws.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\nThe AWS Ops Wheel is a tool that simulates a random selection from a group of participants that weights away from participants recently chosen. For any group, the selection can also be rigged to suggest a particular participant that will be selected in a blatantly obvious (and sometimes hilarious) way.\n\nGet your own in just a few clicks by starting here: [![Launch the Wheel](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/review?filter=active\u0026templateURL=https:%2F%2Fs3-us-west-2.amazonaws.com%2Faws-ops-wheel%2Fcloudformation-template.yml\u0026stackName=AWSOpsWheel)\n\nOr, simply set up a CloudFormation stack using the S3 template url: https://s3-us-west-2.amazonaws.com/aws-ops-wheel/cloudformation-template.yml\n\n**We are aware of an [issue](/../../issues/3) where you can only run this stack in us-west-2 if you launch from this template, we are working on removing this limitation. This limitation does not apply if you build your own stack using the Development Guide below.**\n\nThe endpoint will then be in the CloudFormation Stack Output messages.\n\n## ScreenShots\n### Wheels Table\n![Wheels Table](screenshots/wheels_table.png)\n### Participants Table\n![Participants Table](screenshots/participants_table.png)\n### Wheel (pre-spin)\n![Participants Table](screenshots/wheel_pre_spin.png)\n### Wheel (post-spin)\n![Participants Table](screenshots/wheel_post_spin.png)\n\n# User Guide\n## Concepts\n**Wheel**\n  A group of participants that can be selected from. Users can get a suggestion of a participant from a wheel that is weighted away from recently-chosen participants.\n\n**Participant**\n  A member of a wheel identified by a name, which must be unique, and also a follow-through url when they are chosen. Participants all start with a weight of 1.0.\n\n## Operations\n### Wheel Operations\n- Create a new wheel\n- Edit an existing wheel\n- Delete a wheel\n- Spin the wheel and suggest a participant\n  - ***Notes:*** This does not adjust weighting, so if you're unhappy with the result, you can spin again.\n- Proceed: Accept the suggested participant\n- Reset: Restart all participants to equal weights as 1.0\n\n### Participant Operations\n***Notes:*** Participants aren't shared between wheels\n\n- Add a participant to a wheel\n\t- This requires a name and url that will be opened in a new browser tab when the participant is chosen. A participant begin with a weight of 1.0 which will always be the average weight for all participants.\n- Edit a participant's name and/or url\n- Delete a specific participant from the wheel\n- Rig a specific participant to be selected next\n    - This doesn't change any weighting, but actually bypasses the suggestion algorithm to always suggest the participant until told to proceed.\n    - After proceeding, weights are adjusted as if the participant had been selected normally.\n    - The rigging can be hidden (deceptive) or non-hidden (comical).\n\n### Authentication and User management\nAWS Ops Wheel is protected by Amazon Cognito authentication. It uses [Cognito User Pools](http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html) to manage users that have access to the deployed application.\nBy default, during the initial deployment phase, it creates an `admin` user with a random password that is sent to the email address provided to the `run` script.\nDuring the first attempt to login to the AWS Ops Wheel, the `admin` user will be asked to change the random password to a new one.\n\nIf you need to add more users that have access to the wheel application, you can add them using AWS Cognito web console or using the AWS Cli.\n\n### The Weighting algorithm\n\nAssumption: `total_weight == number_of_participants == len(wheel)`. This is because we only redistribute weights among participants and all participants start with a weight of 1.0. The below is the algorithm in python pseudo-code:\n\n```python\ndef suggest_participant(wheel):\n    target_number =  len(wheel) * random()  # Get a random floating point number between 0 and the total_weight\n    participant = None\n    for participant in wheel:\n        target_number -= participant.weight\n        if target_number \u003c= 0:\n            break\n    return participant\n\ndef select_participant(chosen, wheel):\n    # When there is only one participant in the wheel, the selected participant's weight remains intact.\n    # Otherwise, the remaining participant(s) get a slice of the selected participant's weight. That participant will not be chosen on next spin unless it's rigged.\n\t if len(wheel) \u003e 1:\n\t    weight_slice = chosen.weight / (len(wheel) - 1)\n\t    for participant in wheel:\n\t        if participant == chosen:\n\t            participant.weight = 0\n\t        else:\n\t            participant.weight += weight_slice\n```\n\n# Development Guide\n\n***Notes:*** The development tools are currently only written to be Linux/OSX compatible\n\n## Development Dependencies\n\n- NodeJS 6.10+\n- Python 3\n\t- boto3\n\t- pyaml\n  - pytest\n  - pytest-cov\n  - moto\n- AWSCLI 1.11+\n- An AWS Account you have administrator privileges on\n\n\n## A dedicated IAM User (Optional, but highly-recommended)\n- You should create a dedicated IAM User for ``AWS Ops Wheel`` development\n\n### Create a custom IAM Policy for the User\n\n- Go to the [AWS Create Policy Wizard](https://console.aws.amazon.com/iam/home?region=us-west-2#/policies$new?step=edit)\n- Go to the `JSON` tab and paste in the content of our [policy configuration](https://raw.githubusercontent.com/aws/aws-ops-wheel/master/cloudformation/awsopswheel-create-policy.json)\n- Click `Review Policy`\n- Give it an identifying name (we'll need it for the next step) like *AWSOpsWheelDevelopment*\n\n### Create an IAM user with the policy attached\n\n- Got to the [AWS Create User Wizard](https://console.aws.amazon.com/iam/home?region=us-west-2#/users$new?step=details)\n- Give it a descriptive name like *AWSOpsWheelDevelopmentUser* and check the `Programmatic access` checkbox.  **Note:** It doesn't need to be the same as the name of the policy, but it might help keep your things organized\n- Click `Next: Permissions`\n- Switch to the `Attach existing policies directly` tab and filter on the name you used during the *Create custom Policy* step\n- Click the checkbox next to the policy and click `Next: Review`\n- Click `Create user`\n- On the next page, save the Access key ID and the Secret access key (visible by clicking `Show`) for use in the `AWS Cli Configuration` step.  **Note**: This will be the only opportunity to copy the Secret Access Key for this Access Key ID.  if you don't copy the secret access key now, you'll need to create a new access-key, secret-key pair for the user.\n\n\n## AWS Cli Configuration\nFor the purpose of our work, we will use AWS Cli to simplify management of the resources.\nLater we will add support for the `Launch Stack` button which will be displayed on the GitHub Repo page.\n\nIn `$HOME/.aws/config` add in your credentials configuration and default region, replacing with your IAM user's credentials (or your own access key and secret key if you didn't follow our highly-recommended best-practice).  **Note**: The region can be whatever region you choose, but you should definitely set a default region.  We chose us-west-2 since we're in Seattle and it's close by.\n\n```\n[default]\naws_access_key_id = ACCESS_KEY\naws_secret_access_key = SECRET_KEY\nregion = us-west-2\n```\n\n\n\n## Test the code\n\nCurrently we have unit tests for the API and the UI. \n\nTo run the API unit tests: \n* If you haven't already, go to the ``\u003cPATH_TO_YOUR_WORKSPACE\u003e`` directory and install the required dependencies using:\n  ```\n  pip install -r requirements.txt\n  ```\n* Go to the ``\u003cPATH_TO_YOUR_WORKSPACE\u003e/api`` directory and run:\n  ```\n  pytest --verbose --cov-report term-missing --cov ./ -s\n  ```\n  * If you see this error `NoRegionError: You must specify a region. `, export the region environment variable as follows:\n    `export AWS_DEFAULT_REGION=us-west-2`\n\nTo run the UI unit tests, go to the ``\u003cPATH_TO_YOUR_WORKSPACE\u003e/ui`` directory and run:\n\n```\nnpm run test\n```\n\n## Build and deploy the code\n\nGo to the ``\u003cPATH_TO_YOUR_WORKSPACE\u003e`` directory and run:\n\n```\n$ ./run \\\n  --suffix \u003cSUFFIX, optional with default value as no suffix, so stack name will be 'AWSOpsWheel'\u003e \\\n  --email \u003cEMAIL_ADDRESS, required only during initial stack creation\u003e \\\n  --no-clean \u003cCLEAN_BUILD_DIRECTORY, optional with default value as False. Note that do not clean the build directory before building or remove the deploy working directory\u003e\n```\n\nThis will:\n\n- Create a `./build` directory with all of the build artifacts\n- Package the build artifacts up into a zip file with name based on a hash of the contents and upload it to S3 for lambda deployment\n- Compile the Service CloudFormation Template:\n    - Create the lambda functions for all of the routes in the API\n    - Add policies for lambda functions to be called by the gateway's functions\n    - Create/update the DynamoDB Tables\n    - Create the lambda execution IAM role\n    - Create the swagger configuration for API Gateway that points the paths to their functions\n- Deploy the template directly to CloudFormation through update or create, depending on if it's a new stack\n\n## Start Local Dev Server\nGo to the ``\u003cPATH_TO_YOUR_WORKSPACE\u003e/ui`` directory and run:\n\n```\nnpm run start\n```\n\n# Miscellaneous\n## Import Participant data from .csv file\nTo populate Participant data from .csv file to one of your wheels you can use a tool that is in `utils` folder.\nAll parameters are required.\n\n```\n$ \u003cPATH_TO_YOUR_WORKSPACE\u003e/utils/wheel_feeder.py \\\n  --wheel-url \u003chttps://\u003cyour_api_gateway\u003e.amazonaws.com\u003e \\\n  --wheel-id \u003cTARGET_WHEEL_ID\u003e \\\n  --csv-file-path \u003cPATH_TO_CSV_FILE\u003e \\\n  --cognito-user-pool-id \u003cCOGNITO_USER_POOL_ID\u003e \\\n  --cognito-client-id \u003cCOGNITO_CLIENT_ID\u003e\n```\n\n## List Stacks\nTo list all Stacks that are currently provisioned (or have been in the past):\n\n```\n$ aws cloudformation list-stacks\n```\n\n## Delete Stack\n\nTo delete existing stack:\n\n```\n$ aws cloudformation delete-stack [--suffix SUFFIX_NAME]\n```\n\n## Set up continuous deployment\n\nCreate continuous deployment resources:\n```\naws cloudformation create-stack --stack-name AWSOpsWheel --template-body file://cloudformation/continuous-deployment.yml --parameters ParameterKey=AdminEmail,ParameterValue=example@example.com --capabilities CAPABILITY_NAMED_IAM\n\naws cloudformation wait stack-create-complete --stack-name AWSOpsWheel\n```\nMake sure you have your preferred [CodeCommit access](https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up.html) configured.\n\nThe following assumes that you are using the AWS CLI Credential Helper.\n\nPush to the newly created git repository:\n```\ngit config --global credential.helper '!aws codecommit credential-helper $@'\n\ngit config --global credential.UseHttpPath true\n\ngit remote add app `aws cloudformation describe-stacks --stack-name AWSOpsWheel --query 'Stacks[0].Outputs[?OutputKey==\\`RepositoryCloneUrl\\`].OutputValue' --output text`\n\ngit push app main\n```\n\nWait for the pipeline to finish deploying:\n```\naws cloudformation describe-stacks --stack-name AWSOpsWheel --query 'Stacks[0].Outputs[?OutputKey==`PipelineConsoleUrl`].OutputValue' --output text\n```\n\nGet the URL of the newly deployed application:\n```\naws cloudformation describe-stacks --stack-name AWSOpsWheel-application --query 'Stacks[0].Outputs[?OutputKey==`Endpoint`].OutputValue' --output text\n```\n\n## Wheel Customization\nTo change how fast wheels spin, modify `EASE_OUT_FRAMES` and `LINEAR_FRAMES` in `wheel.jsx`. \nLower values correspond to faster spinning.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws%2Faws-ops-wheel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faws%2Faws-ops-wheel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws%2Faws-ops-wheel/lists"}