{"id":16269732,"url":"https://github.com/tairov/rates-service","last_synced_at":"2025-04-08T15:20:08.848Z","repository":{"id":44587103,"uuid":"454738417","full_name":"tairov/rates-service","owner":"tairov","description":"Rest API for rates retrieval","archived":false,"fork":false,"pushed_at":"2023-07-23T23:13:58.000Z","size":64,"stargazers_count":10,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-14T11:41:30.826Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","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/tairov.png","metadata":{"files":{"readme":"README.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,"publiccode":null,"codemeta":null}},"created_at":"2022-02-02T10:57:00.000Z","updated_at":"2025-02-01T02:05:58.000Z","dependencies_parsed_at":"2024-12-06T15:48:50.085Z","dependency_job_id":"f127fb87-5caf-45ad-93da-0b223c335678","html_url":"https://github.com/tairov/rates-service","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tairov%2Frates-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tairov%2Frates-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tairov%2Frates-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tairov%2Frates-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tairov","download_url":"https://codeload.github.com/tairov/rates-service/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247867361,"owners_count":21009240,"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-10T18:08:59.196Z","updated_at":"2025-04-08T15:20:08.817Z","avatar_url":"https://github.com/tairov.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Infrastructure as Code design decision\n\nThe main design decision in this Terraform project was to split the infrastructure into modules and use Terraform\nworkspaces to manage different environments. This allows for easier management of resources and separation of\nenvironments during development.\nUsing modules in this way makes it easier to add, update, and remove services, because an engineer can do so by\nmaintaining only a couple of files in a single place - main.tf and \u003cENV\u003e.tfvars rather than having to search through the\nhuge single main.tf. It also makes the code more organized, easier to understand, simpler to refactor, since we\neliminated code/logic duplication.\n\nUsing modules in this way makes it easier to add, update, and remove services, because an engineer can do so by\nmaintaining only a couple of files in a single place - `main.tf` and `\u003cENV\u003e.tfvars` rather than having to search through\nthe huge single `main.tf`. It also makes the code more organized, easier to understand, simpler to refactor, since we\neliminated code/logic duplication.\n\n### Using Terraform Workspaces for Development and Github Actions based CI/CD\n\nTerraform workspaces allow for the creation of separate environments within a single configuration. This is useful for\ndevelopment as it allows for easy testing of changes without affecting other environments. It also allows for the\ncreation of specific environments for different stages of the CI/CD pipeline, such as development, staging, and\nproduction.\n\nEssentially we have 2 types of CI/CD pipelines.\n\n1. CI/CD for the infra code (Terraform, ansible, etc.)\n2. CI/CD for the apps \u0026 services\n\nIn both cases the refactored modules repository could be nicely integrated into the pipelines.\n\n#### CI/CD for the client service\n\nSee: [build-and-deploy.yml](.github%2Fworkflows%2Fbuild-and-deploy.yml)\n\nBuild pipeline is implemented in the github actions script. It contains the following steps:\n\n* notify\n* build-and-push-image\n\n#### CI/CD for the Terraform infra\n\nSee: [infra-update.yml](.github%2Fworkflows%2Finfra-update.yml)\n\nI've implemented ready to use github actions script. Beside basic liniting \u0026 setup steps it also contains the following\nwhich must convey the idea I'm proposing:\n\n`Comment terraform plan` - that is executed when **Pull Reqeust** created with changes under `tf/*` path.\nIt creates a comment within Pull Request that will show the implied changes implemented in the commits.\nThis will only work if TF state is stored somehwere remotely like in AWS-S3 or in Terraform Cloud.\n\n`Terraform Apply` - if PR merged then this step will apply all changes on infra\n\nIf the changes are successful in the staging environment, they can then be promoted to the production environment by\nmerging the staging branch into the production branch and running Terraform in the production workspace.\n\n\n\n## Application: Rest API for BTC rates retrieval\n\n### Authentication\n\nHTTP authentication is required to access endpoints. The login and password can be provided through a `.env` file.\n\n### Endpoints:\n\n1. `/rate/\u003ccurrency\u003e` - Returns a JSON response with the current BTC rate for the requested currency.\n\n2. `/health` - Returns a JSON status of the service.\n\n3. `/metrics` - Returns metrics in plain text format supported by Prometheus.\n\n### Terraform setup\n\nBefore running `terraform init`, create a bucket for TF state:\n\n```\naws s3 mb s3://rates-service-terraform-state-bucket\n```\n\nAlso, create a DynamoDB table to enable state locking:\n\n```\naws dynamodb create-table --table-name rates-service-terraform-state-table --attribute-definitions AttributeName=LockID,AttributeType=S --key-schema AttributeName=LockID,KeyType=HASH --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5\n```\n\n### Infra update\n\nIf a pull request is created to update the infrastructure (currently all files under the `deploy/` directory), a separate GitHub Actions workflow will create a comment in the PR with the Terraform plan. Once the PR is merged, Terraform will be executed with the `apply -auto-approve` options.\n\n### Package available on GitHub Container Registry\n\nhttps://github.com/tairov/rates-service/pkgs/container/rates-service\n\n### Production usage\n\nFor simplicity, a WSGI server like `waitress` is not used in development. For production, it is recommended to execute the Flask application through `waitress-serve`.\n\n#### Running via Docker\n\nTo run the service using Docker, execute the following command:\n\n```bash\ndocker run --name rates_service -p 8085:8085 \\\n  --env FLASK_ENV=development \\\n  --env LISTEN_HOST=0.0.0.0 \\\n  --env LISTEN_PORT=8085 \\\n  ghcr.io/tairov/rates-service:master\n```\n\nAfter running the Docker container, you can check if the service is up and running by visiting:\n\n```bash\ncurl http://localhost:8085/health\n```\n\nTo retrieve a JSON response for BTC/USD, use the following command:\n\n```bash\ncurl -u \"john:hello\" http://localhost:8085/rate/USD\n```\n\nPlease note that the authentication credentials (`john:hello`) should match the ones provided in the `.env` file to access the endpoints.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftairov%2Frates-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftairov%2Frates-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftairov%2Frates-service/lists"}