{"id":23042280,"url":"https://github.com/rustshop/rustshop","last_synced_at":"2025-04-10T03:50:03.360Z","repository":{"id":41065435,"uuid":"505019675","full_name":"rustshop/rustshop","owner":"rustshop","description":"Rust Shop is a fake cloud-based software company that you can fork.","archived":false,"fork":false,"pushed_at":"2025-03-07T16:48:48.000Z","size":295,"stargazers_count":76,"open_issues_count":3,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-03T02:06:23.325Z","etag":null,"topics":["aws","nix","rust","shop","terraform"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rustshop.png","metadata":{"files":{"readme":"README.bootstrapping.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-06-19T05:24:30.000Z","updated_at":"2025-02-13T11:35:17.000Z","dependencies_parsed_at":"2024-02-29T20:27:33.683Z","dependency_job_id":"fd11c154-70bf-4284-a916-b6e4c765cb29","html_url":"https://github.com/rustshop/rustshop","commit_stats":{"total_commits":111,"total_committers":1,"mean_commits":111.0,"dds":0.0,"last_synced_commit":"e7300ba328b5c23a9add29f5fe44bb06a2b2ffd6"},"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Frustshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Frustshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Frustshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Frustshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rustshop","download_url":"https://codeload.github.com/rustshop/rustshop/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248154999,"owners_count":21056542,"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":["aws","nix","rust","shop","terraform"],"created_at":"2024-12-15T20:23:56.366Z","updated_at":"2025-04-10T03:50:03.329Z","avatar_url":"https://github.com/rustshop.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bootstrapping the shop\n\nThis document describes how to bootstrap an AWS account\nusing `rustshop` as a base infrastructure for your own \"shop\",\nusing `rustshop`.\n\nThere will be some (relatively short) amount of manual work,\nand then the automation will take over.\n\n## Manual prep-work\n\n### Pick a `\u003cshopname\u003e`\n\nBootstrap scripts will derive bunch of names from it.\nIt should have a solid chance to be unique, otherwise you risk\ninto running into name conflicts for globally unique resource\nnames (like S3 Buckets).\n\nIn our case `\u003cshopname\u003e` is `rustshop`.\n\n### Get a DNS domain (`\u003cdomain\u003e`)\n\nA shop like this will most probably require a DNS domain. Technically\na domain is not strictly necessary until setting up a k8s\ncluster, but `rustshop` requires a base domain name configuration early\nin the process.\n\nYou can use AWS to host your domain, or you can use an external\nDNS hosting provider.\n\nIf you want to use AWS to host the DNS, you might want to create the\nroot account first (see below), and head to Route 53 to purchase it.\n\nIn our case the `\u003cdomain\u003e` is rustshop.org.\n\n### Setup email\n\nWhen generating accounts rustshop will need a root user email\naddress.\n\nBy default it will use a `\u003cemail-user\u003e+\u003caccount-name\u003e@\u003cemail-host\u003e` email\naddress generation system, so you can use one email address,\nwith different labels. Look up \"gmail plus addressing\" if you're\nnot familiar with this scheme. Other email providers often\nsupport it as well.\n\nEmails do not have to be in the `\u003cdomain\u003e`, but can be.\n\nFigure it out - it's beyond of the scope of this document.\n\nIn our case the base email will be `infra@rustshop.org`.\n\n### Create your root account\n\nCreate (if you haven't already) the root account for your\norganization (which will have other sub-accounts).\n\nName the AWS account `\u003cshopname\u003e-root`. Consider using`\u003cemail-user\u003e+root@\u003cemail-domain\u003e`\nas the account email to be consistent.\n\n**Set a strong password.**\n\nYou might want to watch https://learn.cantrill.io/courses/730712/lectures/24950112\nfor some relevant instruction.\n\n**Add MFA for this account.** Seriously - always set MFA on all your accounts.\nYou do not want to pay a lot of money because your password leaked and now\nyour account is mining some crypto.\n\nCreate an initial \"Cost Budget\" and add an alert in it. If anything goes\nwrong you want to know that you're paying more than expected.\n\nCreate `iamadmin` IAM admin user with `AdministratorAccess` policy. Make sure\nto allow it the \"Access key - Programmatic access\" option -\nwe are going to need it soon. You might want to watch\nhttps://learn.cantrill.io/courses/730712/lectures/24950119 for instructions.\n\nIf you selected \"Access key - Programmatic access\" option, you should be presented\nwith access keys details. Keep it around safe locally. It will be need soon.\n\nThough it isn't strictly necessary, if you are like me and AWS is a bit new\nto you consider enrolling into\n[Adrian Cantrill's AWS Certified Solutions Architect - Associate course](https://learn.cantrill.io/p/aws-certified-solutions-architect-associate-saa-c02).\nThe helpful videos linked above are the freely accessible parts of the\nmuch larger course, and I can highly recommend it.\n\n\n### Create your shop's monorepo git repository\n\nMake sure you have Nix installed and set up with flake support.\nSee [README.onboarding](README.onboarding) for help.\n\nYou can start with `git init .`, or create it on remotely\nand clone locally.\n\nCopy the [flake.nix](rustshop/templates/flake.nix) to the\nroot dir. Then run:\n\n```sh\ngit add flake.nix\nnix flake update\n```\n\nand you should finally be able to get the rustshop shell\nworking with:\n\n```sh\nnix develop\n```\n\nFrom now on `nix develop` will be your entry point to working\nwith your shop.\n\nA `shop` command appear in your shell:\n\n```\nmyshop$ shop\nrustshop \nRustshop binary\n\nUSAGE:\n    shop \u003cSUBCOMMAND\u003e\n\nOPTIONS:\n    -h, --help    Print help information\n\nSUBCOMMANDS:\n    add          Manually add rustshop components to track (see `bootstrap` instead)\n    bootstrap    Set up new amazon account/organization\n    configure    Configure user settings\n    get          Display certain values\n    help         Print this message or the help of the given subcommand(s)\n    switch       Switch current context (account, cluster, namespace)\n\nHelp and feedback: https://github.com/rustshop/rustshop/discussions/categories/help-general\n```\n\n## Bootstrap your infra\n\n### Set up `aws` command profile\n\n**Make sure the credentials here are from the IAM `iamadmin` user**,\nand not from the root account root user!\n\n`aws` command should be available in shell and you can configure a profile\nusing `env RUSTSHOP_NO_BIN_WRAP=true aws configure --profile \u003cshopname\u003e-root` like this:\n\nTODO: The `env RUSTSHOP_NO_BIN_WRAP=true` is needed because shop config is not yet\nconfigured which messes up with `aws` wrapper.\n\n```\ninfra$ aws configure\nAWS Access Key ID [None]: SOMEKEYIDYOUVEGOT\nAWS Secret Access Key [None]: SomeSecretKey1ThatAmazonProduced\nDefault region name [None]: us-east-1\nDefault output format [None]:\n```\n\nThe Key ID and Secret Access Key should be provided to you\nwhen you created `iamadmin` user.\n\nYou can use `aws configure list-profiles` to list all profiles.\n\n### Bootstrap your account\n\nRun:\n\n```sh\nshop bootstrap shop --domain \u003cdomain\u003e --email \u003cemail\u003e \u003cshopname\u003e\nshop bootstrap account prod --email \u003cemail\u003e\n```\n\nExample:\n\n```sh\nshop bootstrap shop --domain rustshop.org --email admin@rustshop.org rustshop\nshop bootstrap account prod --email admin@rustshop.org\n\n````\n\nFollow the output, and in case of any issues\n[try asking for help](https://github.com/rustshop/rustshop/discussions/categories/help-general).\n\nYou might verify in the AWS Console, under Organizations product that and organization was\ncreated, with a `\u003cshopname\u003e-prod` sub-account.\n\n\n### Bootstrap prod k8s cluster\n\nSince everything is already installed, basic infrastructure bootstrapped and `rustshop`\nwraps `kops` to automatically supply the account-specific values, bootstrapping\na fresh kubernetes cluster is very simple.\n\nSwitch to the `prod` account:\n\n```\nshop switch account prod\n```\n\n#### Bootstrap cluster using `shop bootstrap`\n\n`rustshop` can automate the k8s cluster bootstrapping by:\n\n* creating a DNS zone for you and prompting you to configure it\n* creating the `kops` cluster configuration by calling `kops create cluster` with right arguments\n\nHowever since it is a multi-step process that you probably want\nto customize and understand, after this section we will describe\nthe manual procedure that `shop bootstrap cluster` is automating.\n\nCall:\n\n```\nshop switch account prod\nshop bootstrap cluster prod --minimal\n```\n\nread, the prompts, configure and verify your DNS setup.\n\nNote that at the time of writing `--minimal` option does\nnot lower the etcd EBS size to `1` and doesn't set up spot\ninstance settings on the nodes.\n\nWhen ready call:\n\n```\nshop bootstrap cluster prod --minimal --dns-ready\n```\n\nthen use `kops edit cluster` and `kops edit ig`, etc to customize\nto your desired settings and when ready, call:\n\n```\nkops update cluster --yes\n```\n\n#### Bootstrap cluster manually\n\n### DNS\n\n`kops` cluster requires a DNS zone that it can use. We are going to use\nRoute 53 to host it.\n\nPick a DNS name for your cluster. `prod.k8s.\u003cdomain\u003e` is recommended.\n\nTo create the hosted zone for the cluster run:\n\n```sh\nID=$(uuidgen) \u0026\u0026 \\\naws route53 create-hosted-zone \\\n--name prod.k8s.\u003cdomain\u003e \\\n--caller-reference $ID \\\n| jq .DelegationSet.NameServers\n```\n\nYou can use `aws route53 list-hosted-zones` and `aws route53 get-hosted-zone --id \u003czone-id\u003e`\nto discover the hosted zones you've created.\n\nThe output of this command should give you a list of DNS names to add as a NS record\nto your main domain. Depending on your DNS hosting provider, the details might\ndiffer, but it comes down to creating 4 NS records for `prod.k8s` in your \u003cdomain\u003e host\nzone configuration.\n\n\nVerify your DNS with:\n\n```sh\nping prod.k8s.\u003cdomain\u003e\ndig prod.k8s.\u003cdomain\u003e\n```\n\nDo not move forward until the DNS is ready.\n\nCreate cluster configuration:\n\n```sh\nkops create cluster \\\n  --cloud aws \\\n  --zones \"us-east-1f\" \\\n  --master-count 1  \\\n  --master-size t3a.small \\\n  --master-volume-size 8 \\\n  --node-count 1 \\\n  --node-size t3a.small \\\n  --node-volume-size 8 \\\n  --networking=calico --topology public\n```\n\nIf you are a cheapskate like me, you can\nchange the EBS volumes to bare minimums with:\n\n```\nkops edit cluster\n```\n    \nand add `volumeSize: 1` on each etcd instances (https://unix.stackexchange.com/a/598838/4389), along with\n    \n```\n    manager:\n      backupInterval: 12h0m0s\n```\n    \nto avoid accumulating a lot of backup in the state s3 backup.\n\nAnd use spot instances:\n\n```\nkops get ig\nkops edit ig \u003cmasterig\u003e # add `maxPrice: \"0.01\"\nkops edit ig \u003cnodesig\u003e # add `maxPrice: \"0.01\"\n```\n\nAfter tweaking and verifying the settings you can deploy the cluster with:\n\n```\nkops update cluster --yes\n```\n\nThis process can easily create up to 30 minutes, so be patient.\n\nYou might need to run:\n\n```\nkops export kubecfg --admin\n```\n\nto update the kubectl context in `~/.kube/config`\n\nAfter the cluster is bootstrapped you should be\nable to execute:\n\n```\nkubectl get nodes\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustshop%2Frustshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frustshop%2Frustshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustshop%2Frustshop/lists"}