├── .gitignore ├── LICENSE ├── README.md ├── notes.md ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Startup-Samples 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS Cost Optimization Resources for Startups 2 | Welcome. This reference has been prepared by Startup Solution Architects at AWS to help Startups easily find additional resources that provide specific guidance on various techniques for effective cost optimization. 3 | 4 | We hope this proves useful as you navigate the various options available to you for maximizing the value you can get out of running on AWS. As always, should you have questions on anything, please don't hesitate to contact your local startup team. If you aren't already in contact with them, simply visit https://aws.amazon.com/startups/ and click on the `Get In Touch` button. 5 | 6 | 7 | 8 | ## Contents 9 | 10 | - [Useful Tools](#useful-tools) 11 | - [AWS Budgets](#aws-budgets) 12 | - [Cost Explorer](#cost-explorer) 13 | - [Trusted Advisor](#trusted-advisor) 14 | - [Anomaly detection](#anomaly-detection) 15 | - [AWS Organizations](#aws-organizations) 16 | - [Tagging](#tagging) 17 | - [Pricing Calculator](#pricing-calculator) 18 | - [Cost & Usage Report](#cost--usage-report) 19 | - [Well-Architected Framework](#well-architected-framework) 20 | - [Cost Optimization Workshop](#cost-optimization-workshop) 21 | - [No Effort Options](#no-effort-options) 22 | - [Reserved Instances](#reserved-instances) 23 | - [Savings Plans](#savings-plans) 24 | - [AWS Product and Services](#aws-product-and-services) 25 | - [Cloudwatch](#cloudwatch) 26 | - [Data Transfer Out](#data-transfer-out) 27 | - [DynamoDB](#dynamodb) 28 | - [Application auto scaling](#application-auto-scaling) 29 | - [Storage-IA table class](#storage-ia-table-class) 30 | - [general guidance](#general-guidance) 31 | - [EBS](#ebs) 32 | - [EC2](#ec2) 33 | - [ECS](#ecs) 34 | - [EKS](#eks) 35 | - [Graviton](#graviton) 36 | - [Lambda](#lambda) 37 | - [RDS](#rds) 38 | - [S3](#s3) 39 | - [Spot](#spot) 40 | - [CloudWatch](#cloudwatch) 41 | 42 | 43 | 44 | 45 |
46 |
47 |
48 | 49 | # Useful Tools 50 | 51 | ## AWS Budgets 52 | Get alerted and take action when AWS spend reaches a threshold: 53 | 54 | https://aws.amazon.com/aws-cost-management/aws-budgets/ 55 | 56 | ## Cost Explorer 57 | Analyze your costs by region, service, tag, and more: 58 | 59 | https://aws.amazon.com/aws-cost-management/aws-cost-explorer/ 60 | 61 | make sure to checkout the optimization recommendations 62 | https://aws.amazon.com/blogs/aws-cloud-financial-management/launch-resource-optimization-recommendations/ 63 | 64 | 65 | ## Trusted Advisor 66 | Trusted Advisor gives you automated guidance for cost optimization, detecting under-utilized instances and other areas of improvement: 67 | 68 | https://aws.amazon.com/premiumsupport/technology/trusted-advisor/ 69 | 70 | 71 | ## Anomaly detection 72 | 73 | AWS Cost Anomaly Detection is an AWS Cost Management feature that uses machine learning to continuously monitor your cost and usage to detect unusual spends. 74 | 75 | https://docs.aws.amazon.com/cost-management/latest/userguide/manage-ad.html 76 | 77 | 78 | 79 | ## AWS Organizations 80 | 81 | (More info coming soon) 82 | 83 | Use AWS Accounts as an accounting and security boundary, while keeping centralized billing and security controls using AWS Organizations: 84 | https://aws.amazon.com/organizations/ 85 | 86 | This japanese blog post describes how you can use Control Tower to ease multi account setups 87 | https://aws.amazon.com/jp/blogs/startup/multi-accounts-and-control-tower/ 88 | 89 | 90 | 91 | ## Tagging 92 | Tagging is a powerful way to organize and allocate costs: 93 | 94 | https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html 95 | 96 | 97 | ## Pricing Calculator 98 | Estimate your workload costs ahead of time: 99 | 100 | https://calculator.aws/ 101 | 102 | 103 | ## Cost & Usage Report 104 | Detailed reports can be scheduled for export as CSV for analysis: 105 | 106 | https://aws.amazon.com/aws-cost-management/aws-cost-and-usage-reporting/ 107 | 108 | 109 | ## Well-Architected Framework 110 | The Well-Architected Framework gives best practice guidance on Cost Optimization and other topics: 111 | 112 | https://docs.aws.amazon.com/wellarchitected/latest/framework/welcome.html 113 | 114 | Inside your AWS Console, you can use the Well-Architected Tool to interactively go through the framework's guidance: 115 | https://aws.amazon.com/well-architected-tool/ 116 | 117 | Learn more about the Cost Optimization pillar: 118 | https://aws.amazon.com/products/management-tools/partner-solutions/#Resource_and_Cost_Optimization 119 | 120 | 121 | ## Cost Optimization Workshop 122 | To get hands-on with these recommendations, the Activate Next Workshop shows you how to design cost-effective workloads: 123 | 124 | https://activate-next.workshop.aws/ 125 | 126 | 127 |
128 |
129 | 130 | # No Effort Options 131 | 132 | 133 | ## Reserved Instances 134 | In return for a commitment of 1 or 3 years, AWS offers discounts on EC2 instance usage of up to 75%: 135 | 136 | https://aws.amazon.com/aws-cost-management/aws-cost-optimization/reserved-instances/ 137 | 138 | 139 | ## Savings Plans 140 | Benefit from discounts on compute usage, across EC2, Fargate, and Lambda, with Compute Savings Plans: 141 | 142 | https://aws.amazon.com/savingsplans 143 | 144 | 145 |
146 |
147 | 148 | 149 | # AWS Product and Services 150 | 151 | ## Cloudwatch 152 | Make sure you have set retention policies on logs 153 | https://aws.amazon.com/blogs/infrastructure-and-automation/reduce-log-storage-costs-by-automating-retention-settings-in-amazon-cloudwatch/ 154 | 155 | if you are using [Custom Metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html) consider switching to Embedded Metric Format (EMF). 156 | https://aws.amazon.com/about-aws/whats-new/2019/11/amazon-cloudwatch-launches-embedded-metric-format/ 157 | The main difference is that EMF doesn't incur a charge when submitting a custom metric. 158 | 159 |
160 |
161 | 162 | ## Data Transfer Out 163 | 164 | - Analyze Data Transfer Costs using Cost Explorer 165 | This blog post goes into more detail. 166 | https://aws.amazon.com/blogs/mt/using-aws-cost-explorer-to-analyze-data-transfer-costs/ 167 | 168 | 169 | - Use Private IP for Internal Services Communication 170 | if you deploy ec2 instances in a public subnet, you can choose to have a public IP. If you are communicating between two ec2 instances in the same VPC, make sure to use the private IP so your traffic doesn't leave the AWS network. 171 | https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html 172 | 173 | 174 | - Use VPC End-Points for S3 and DynamoDB 175 | Avoid the anti pattern of inter service communication going out to the internet and coming back in. Use Gateway endpoints! They are free. 176 | https://docs.aws.amazon.com/vpc/latest/privatelink/gateway-endpoints.html 177 | 178 | 179 | - Use interface endpoints for other services. 180 | For services other than S3 and DynamoDB you need an interface endpoint. 181 | https://docs.aws.amazon.com/vpc/latest/privatelink/aws-services-privatelink-support.html 182 | https://aws.amazon.com/privatelink/pricing/ 183 | Min charge is 0.013 * 730 = $9.49 184 | And then $0.01 / PB 185 | 186 | Look at this if your DTO for interservice communication is higher than this. 187 | 188 | - Consider using CloudFront to reduce Data Transfer Out Costs 189 | Cloudfront is a bit cheaper and has a free tier. As a side bonus you also get performance benefit. https://aws.amazon.com/about-aws/whats-new/2021/11/aws-price-reduction-data-transfers-internet/ 190 | 191 | 192 | 193 | - Managed services often exempt you from data transfer charges. 194 | It's important to understand what charges you incur for data transfer. It's worth noting that aside from removing undifferentiated heavy lifting, using managed services also exempts you from certain data transfer charges within a region. 195 | To illustrate this, this blog explores data transfer costs in relation to RDS. 196 | https://aws.amazon.com/blogs/architecture/exploring-data-transfer-costs-for-aws-managed-databases/ 197 | 198 |
199 |
200 | 201 | ## DynamoDB 202 | 203 | 204 | - writes are 5x more expensive than reads. e.g on-demand: https://aws.amazon.com/dynamodb/pricing/on-demand/ 205 | - attribute names contribute to storage. Use shorter names if storage costs are an issue 206 | - rethink if attribute values need to be in dynamo. a good example is storing image data. rather than storing in Dynamodb, does it make more sense to store it in S3 and store just the key in Dynamo 207 | - breaking up an item into multiple items may make sense depending on the access pattern. 208 | - Use TTL for data that loses significance after a period of time: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html 209 | 210 | 211 | ### Application auto scaling 212 | Use Application auto scaling to adjust capacity dynamically to traffic. 213 | Keep in mind, DynamoDB read/write capacity is automatically adjusted according to an application traffic. 214 | There is, however, a limit on the number of times you can adjust the Read/Write capacity / day. This means you can't reduce write capacity if the read capacity is reduced by more than the allowed number of times. 215 | Therefore in this case, you might pay more because of the unnecessary high write capacity. 216 | 217 | A strategy here is to adjust only the write capacity on the schedule while fixing the read capacity. 218 | In this way you can reduce DynamoDB costs incurred by the write capacity, which we already know is 5x more expensive than read capacity. 219 | 220 | https://aws.amazon.com/blogs/database/amazon-dynamodb-auto-scaling-performance-and-cost-optimization-at-any-scale/ 221 | 222 | documentation: https://docs.aws.amazon.com/autoscaling/application/userguide/services-that-can-integrate-dynamodb.html 223 | 224 | If DynamoDB storage cost exceeds 50 percent of the cost of throughput (reads and writes) consistently, then the DynamoDB Standard-IA table class is the most economical choice for you. 225 | 226 | ### Storage-IA table class 227 | 228 | If DynamoDB storage cost exceeds 50 percent of the cost of throughput (reads and writes) consistently, then the DynamoDB Standard-IA table class is the most economical choice for you. 229 | Good examples of potential candidates are tables that store infrequently accessed data, such as application logs, old social media posts, e-commerce order history, and past gaming achievements. 230 | https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.tableclasses.html 231 | https://aws.amazon.com/dynamodb/pricing/on-demand/ 232 | 233 | 234 | ### general guidance 235 | How do I optimize costs with Amazon DynamoDB? 236 | https://aws.amazon.com/premiumsupport/knowledge-center/dynamodb-optimize-costs/ 237 | 238 | Safely reduce the cost of your unused Amazon DynamoDB tables using on-demand mode 239 | https://aws.amazon.com/ko/blogs/database/safely-reduce-the-cost-of-your-unused-amazon-dynamodb-tables-using-on-demand-mode/ 240 | 241 | 242 |
243 |
244 | 245 | 246 | ## EBS 247 | In general, for almost all workloads, if you are on GP2 you will benefit from moving to GP3. 248 | https://aws.amazon.com/about-aws/whats-new/2020/12/introducing-new-amazon-ebs-general-purpose-volumes-gp3/ 249 | 250 | Find out how much you stand to save with this EBS GP2 to GP3 Cost savings calculator: https://d1.awsstatic.com/product-marketing/Storage/EBS/gp2_gp3_CostOptimizer.dd5eac2187ef7678f4922fcc3d96982992964ba5.xlsx 251 | 252 | Here's a blog post describing how you can migrate your Amazon EBS volumes from gp2 to gp3 and save up to 20% on costs: https://aws.amazon.com/blogs/storage/migrate-your-amazon-ebs-volumes-from-gp2-to-gp3-and-save-up-to-20-on-costs/ 253 | 254 |
255 |
256 | 257 | 258 | ## EC2 259 | 260 | Turn off instances you are not using. 261 | 262 | Deploy the ready-to-use Instance Scheduler, allowing you to start and stop instances on a schedule to help save costs. 263 | https://aws.amazon.com/solutions/implementations/instance-scheduler/ 264 | 265 | Make sure to rightsize your instances. You can manually eyeball from cloudwatch or use helpful tools like Compute Optimizer. 266 | https://aws.amazon.com/blogs/aws/aws-compute-optimizer-your-customized-resource-optimization-service/ 267 | https://aws.amazon.com/blogs/compute/optimizing-ec2-workloads-with-amazon-cloudwatch/ 268 | https://docs.aws.amazon.com/whitepapers/latest/cost-optimization-right-sizing/identifying-opportunities-to-right-size.html 269 | https://docs.aws.amazon.com/whitepapers/latest/cost-optimization-right-sizing/tips-for-right-sizing-your-workloads.html 270 | 271 | 272 | 273 | Consider alternate processors (often 10% cheaper) 274 | https://aws.amazon.com/ec2/amd/ 275 | 276 | ARM based (up to 40% better price over performance.) 277 | https://aws.amazon.com/ec2/graviton/ 278 | 279 | (more on [graviton below](#graviton)) 280 | 281 | Learn how to leverage [Spot in the section below](#spot) 282 | 283 | Use Auto Scaling to use just the compute you need. No need to over-provision for peak load. 284 | https://aws.amazon.com/autoscaling/ 285 | 286 | With over 400 instance types available, the Instance Explorer can help you find the right one for your needs: 287 | https://aws.amazon.com/ec2/instance-explorer/ 288 | 289 | 290 | Learn how AWS Cost Explorer Rightsizing Recommendations Integrates with AWS Compute Optimizer 291 | https://aws.amazon.com/ko/blogs/aws-cloud-financial-management/launch-aws-cost-explorer-rightsizing-recommendations-integrates-with-aws-compute-optimizer/ 292 | 293 | 294 |
295 |
296 | 297 | 298 | ## ECS 299 | 300 | Make use of automated tagging via the `propogate tags` option. This will help increase visibility into costs 301 | https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-using-tags.html 302 | 303 | 304 | Container insights is super helpful for gaining visibility into what your containers are doing. This blog introduces the product and what you can do with it 305 | https://aws.amazon.com/blogs/mt/introducing-container-insights-for-amazon-ecs/ 306 | 307 | For a full list of Amazon ECS Container Insights metrics, see Amazon ECS Container Insights Metrics https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-metrics-ECS.html 308 | 309 | ECS Fargate is a highly recommended way for startups to deploy their applications as it removes undifferentiated heavy lifting of managing instances. This blog post is a cost optimization checklist to help you optimize on cost. 310 | https://aws.amazon.com/blogs/containers/cost-optimization-checklist-for-ecs-fargate/ 311 | 312 | To further optimize you can use Fargate spot for significant cost savings 313 | https://aws.amazon.com/blogs/compute/deep-dive-into-fargate-spot-to-run-your-ecs-tasks-for-up-to-70-less/ 314 | 315 | But you need to architect for handling the interruptions if the computer resources get reclaimed. 316 | This japanese blog post describes how to do that. 317 | https://aws.amazon.com/blogs/containers/graceful-shutdowns-with-ecs/ 318 | [JP version] 319 | https://aws.amazon.com/jp/blogs/news/graceful-shutdowns-with-ecs/ 320 | 321 | this workshop guides you through how to deploy using fargate spot 322 | https://ec2spotworkshops.com/ecs-spot-capacity-providers/module-2.html 323 | 324 | 325 |
326 |
327 | 328 | 329 | ## EKS 330 | 331 | Make use of automated tagging. 332 | https://aws.amazon.com/about-aws/whats-new/2022/08/amazon-eks-cluster-level-cost-allocation-tagging/ 333 | 334 | 335 | There are various tools and plugins you should know about to help you optimize your EKS usage. 336 | 337 | AWS Node Terimination handler helps you gracefully handle EC2 instance shutdown within Kubernetes. https://github.com/aws/aws-node-termination-handler 338 | This is important for auto scaling and leveraging spot. 339 | 340 | [Karpenter](https://karpenter.sh/) is a high performance auto scaling solution. Use it with Spot to reap savings. https://aws.amazon.com/blogs/containers/using-amazon-ec2-spot-instances-with-karpenter/ 341 | 342 | This blog post describes recommended tips for cost optimization in AWS. 343 | https://aws.amazon.com/blogs/containers/cost-optimization-for-kubernetes-on-aws/ 344 | 345 | These plugins will help give visibility into your costs 346 | https://github.com/hjacobs/kube-resource-report 347 | 348 | 349 | another helpful tool for cost visibility is [Kubecost](https://github.com/kubecost/kubectl-cost). Kubecost enables users to view costs broken down by Kubernetes resources including pods, nodes, namespaces, labels, and more. 350 | https://aws.amazon.com/blogs/containers/aws-and-kubecost-collaborate-to-deliver-cost-monitoring-for-eks-customers/ 351 | 352 | use it in conjunction with 353 | https://github.com/kubecost/cost-model 354 | 355 | 356 | AWS also has cluster level cost allocation tagging. 357 | https://aws.amazon.com/about-aws/whats-new/2022/08/amazon-eks-cluster-level-cost-allocation-tagging/ 358 | 359 | [JP version] 360 | https://aws.amazon.com/jp/about-aws/whats-new/2022/08/amazon-eks-cluster-level-cost-allocation-tagging/ 361 | 362 | 363 | This plugin is used to scale in and out the deployments based on time of day. This can result in significant cost-savings when there are many deployments that only need to be available during business hours. 364 | https://github.com/hjacobs/kube-downscaler 365 | 366 |
367 |
368 | 369 | 370 | ## Graviton 371 | 372 | This github repo is maintained by the AWS Graviton team. It is meant to help new users start using the Arm-based AWS Graviton and Graviton2 processors which power the latest generation of Amazon EC2 instances. While it calls out specific features of the Graviton processors themselves, this repository is also generically useful for anyone running code on Arm. 373 | https://github.com/aws/aws-graviton-getting-started 374 | 375 | If you want to get hands on there is a workshop you can follow: 376 | https://graviton2-workshop.workshop.aws/en/gettingstarted.html 377 | 378 | In general moving to a managed service is an easy way to reap immediate savings. this blog post outlines some of the considerations for RDS and Graviton: 379 | https://aws.amazon.com/blogs/database/key-considerations-in-moving-to-graviton2-for-amazon-rds-and-amazon-aurora-databases/ 380 | 381 |
382 |
383 | 384 | 385 | ## Lambda 386 | 387 | Understand how Lambda billing works. 388 | https://aws.amazon.com/blogs/aws/new-for-aws-lambda-1ms-billing-granularity-adds-cost-savings/ 389 | 390 | In general the formula is 391 | > Duration = Execution time (sec) * Function Size (allocated memory GB) 392 | > Cost = Number of Invocations * Duration 393 | 394 | This blog post series provides good guidance on how to optimize your lambda. Focus on Rightsizing using [AWS Lambda Powertuning Tool](https://github.com/alexcasalboni/aws-lambda-power-tuning) as the lowest hanging fruit 395 | Part 1: https://aws.amazon.com/ko/blogs/compute/optimizing-your-aws-lambda-costs-part-1/ 396 | Part 2: https://aws.amazon.com/ko/blogs/compute/optimizing-your-aws-lambda-costs-part-2/ 397 | 398 | 399 | [Provisioned concurrency](https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html) is primarily intended to reduce cold start times. It can, however, help reduce cost when you have a constant steady state amount of invocations. This is because the duration cost of lambda in provisioned concurrency is ~70% less than on-demand. **Only attempt this if you are very sure about your utilization** 400 | https://aws.amazon.com/lambda/pricing/ 401 | 402 | 403 | Review if graviton is a practical option: 404 | https://github.com/aws/aws-graviton-getting-started#lambda-on-graviton 405 | 406 | 407 | Explore if commercial options like [Savings Plans](https://aws.amazon.com/about-aws/whats-new/2020/02/aws-lambda-participates-in-compute-savings-plans/) are a good fit. See if you can bundle this with other compute that you use. 408 | 409 | 410 | 411 | This workshop will give you hands on guidance on different serverless optimization scenarios 412 | Serverless Optimization Workshop: https://catalog.us-east-1.prod.workshops.aws/workshops/2d960419-7d15-44e7-b540-fd3ebeb7ce2e/ 413 | 414 | To increase visibility, this blog walks you through logging and introduces [Embedded Metric Format](https://aws.amazon.com/about-aws/whats-new/2019/11/amazon-cloudwatch-launches-embedded-metric-format/) for custom metrics 415 | https://aws.amazon.com/ko/blogs/compute/operating-lambda-logging-and-custom-metrics/ 416 | 417 | 418 |
419 |
420 | 421 | ## RDS 422 | 423 | The lowest hanging Fruit is to migrate to Graviton based instances. More info on considerations in the [graviton section](#graviton) 424 | 425 | Understanding how you are using your RDS instances is key to RDS optimization. A highly effective tool to aid you in this is `Performance Insights` 426 | https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PerfInsights.html 427 | 428 | 429 | These links provide practical hands on workshops to show you how to leverage Performance Insights to get the most out of your RDS instances 430 | 431 | Performance Monitoring Workshop for RDS PostgreSQL and Aurora PostgreSQL - https://catalog.us-east-1.prod.workshops.aws/workshops/31babd91-aa9a-4415-8ebf-ce0a6556a216/en-US 432 | 433 | 434 | RDS MySQL Performance Insights Lab - https://catalog.us-east-1.prod.workshops.aws/workshops/0135d1da-9f07-470c-9845-44ead3c78212/en-US/lab8 435 | 436 | This workshop is part of a new program we run with startups to help developers be better practioners of relational databases. If you are interested in running this for your startup, please get in touch with us. 437 | DB4Dev workshop - https://catalog.workshops.aws/db4devs/en-US 438 | 439 |
440 |
441 | 442 | ## S3 443 | 444 | key tip: "_If you don't need it, delete it_" 445 | 446 | 447 | 448 | This workshop walks you through S3 Cost optimization tips: https://catalog.us-east-1.prod.workshops.aws/workshops/f238037c-8f0b-446e-9c15-ebcc4908901a/en-US/002-services/002-storage/003-s3 449 | 450 | 451 | This blog post will outline how you can optimize for both predictable and dynamic access patterns - https://aws.amazon.com/blogs/storage/amazon-s3-cost-optimization-for-predictable-and-dynamic-access-patterns/ 452 | 453 | Use the S3 Storage Classes to optimize your storage costs: 454 | https://aws.amazon.com/s3/storage-classes 455 | 456 |
457 |
458 | 459 | ## Spot 460 | AWS Spot Instances are an amazing option allowing you to take advantage of spare capacity in AWS datacenters to receive up to 90% discounts on your instances. Spot is available to use with EC2 instances directly and also with ECS and EKS. You can learn more here 461 | [https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html) 462 | 463 | The catch is if AWS needs that spare capacity, you will receive a 2 min warning before your instance is reclaimed. 464 | 465 | To learn how you might take advantage of this, you can try yourself in this workshop: 466 | https://ec2spotworkshops.com/ 467 | 468 | Learn more about Spot: https://aws.amazon.com/ec2/spot 469 | 470 |
471 |
472 | 473 | ## CloudWatch 474 | Custom Metrics can be pushed to CloudWatch from your application: 475 | https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html 476 | 477 | Viewing standard and custom metrics in a CloudWatch dashboard: 478 | https://catalog.workshops.aws/observability/en-US/metrics/viewmetrics 479 | 480 | Reduce log-storage costs by automating retention settings in Amazon CloudWatch 481 | https://aws.amazon.com/ko/blogs/infrastructure-and-automation/reduce-log-storage-costs-by-automating-retention-settings-in-amazon-cloudwatch/ 482 | -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Contents 4 | 5 | - [Quick Brief](#quick-brief) 6 | - [Technical Stuff](#technical-stuff) 7 | 8 | 9 | 10 | # Quick Brief 11 | 12 | For each topic we basically want to 13 | 14 | * point to specific documentation 15 | * provide prescriptive guidance on what to do 16 | * point to workshops or code samples which provide guidance for reader to self experiment 17 | 18 | 19 | # Technical Stuff 20 | 21 | When setting up, do 22 | ``` 23 | npm install 24 | ``` 25 | 26 | Before commiting run 27 | ``` 28 | npx doctoc . --github --title "## Contents" 29 | ``` -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cost-optimization", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@textlint/ast-node-types": { 8 | "version": "12.2.1", 9 | "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-12.2.1.tgz", 10 | "integrity": "sha512-NXYza6aG1+LdZ4g83gjRhDht+gdrTjJYkdcQhpvzNCtTar/sVpaykkauRcAKLhkIWrQpfb311pfMlU6qNDW76Q==" 11 | }, 12 | "@textlint/markdown-to-ast": { 13 | "version": "12.2.1", 14 | "resolved": "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-12.2.1.tgz", 15 | "integrity": "sha512-p+LlVcrgHnSNEWWflYU412uu+v4Cejs6hmI4SgZCheNg4u7Ik78aKgpe4jT5BhjLSBZ/KP6IrJxtCUOoJIUWmQ==", 16 | "requires": { 17 | "@textlint/ast-node-types": "^12.2.1", 18 | "debug": "^4.3.4", 19 | "remark-footnotes": "^3.0.0", 20 | "remark-frontmatter": "^3.0.0", 21 | "remark-gfm": "^1.0.0", 22 | "remark-parse": "^9.0.0", 23 | "traverse": "^0.6.6", 24 | "unified": "^9.2.2" 25 | } 26 | }, 27 | "@types/mdast": { 28 | "version": "3.0.10", 29 | "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", 30 | "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", 31 | "requires": { 32 | "@types/unist": "*" 33 | } 34 | }, 35 | "@types/unist": { 36 | "version": "2.0.6", 37 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 38 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 39 | }, 40 | "anchor-markdown-header": { 41 | "version": "0.5.7", 42 | "resolved": "https://registry.npmjs.org/anchor-markdown-header/-/anchor-markdown-header-0.5.7.tgz", 43 | "integrity": "sha512-AmikqcK15r3q99hPvTa1na9n3eLkW0uE+RL9BZMSgwYalQeDnNXbYrN06BIcBPfGlmsGIE2jvkuvl/x0hyPF5Q==", 44 | "requires": { 45 | "emoji-regex": "~6.1.0" 46 | } 47 | }, 48 | "bail": { 49 | "version": "1.0.5", 50 | "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", 51 | "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" 52 | }, 53 | "ccount": { 54 | "version": "1.1.0", 55 | "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", 56 | "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" 57 | }, 58 | "character-entities": { 59 | "version": "1.2.4", 60 | "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", 61 | "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" 62 | }, 63 | "character-entities-legacy": { 64 | "version": "1.1.4", 65 | "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", 66 | "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" 67 | }, 68 | "character-reference-invalid": { 69 | "version": "1.1.4", 70 | "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", 71 | "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" 72 | }, 73 | "debug": { 74 | "version": "4.3.4", 75 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 76 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 77 | "requires": { 78 | "ms": "2.1.2" 79 | } 80 | }, 81 | "doctoc": { 82 | "version": "2.2.0", 83 | "resolved": "https://registry.npmjs.org/doctoc/-/doctoc-2.2.0.tgz", 84 | "integrity": "sha512-PtiyaS+S3kcMbpx6x2V0S+PeDKisxmjEFnZsuYkkj4Lh3ObozJuuYh9dM4+sX02Ouuty8RF2LOCnIbpu/hWy/A==", 85 | "requires": { 86 | "@textlint/markdown-to-ast": "^12.1.1", 87 | "anchor-markdown-header": "^0.5.7", 88 | "htmlparser2": "^7.2.0", 89 | "minimist": "^1.2.6", 90 | "underscore": "^1.13.2", 91 | "update-section": "^0.3.3" 92 | } 93 | }, 94 | "dom-serializer": { 95 | "version": "1.4.1", 96 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", 97 | "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", 98 | "requires": { 99 | "domelementtype": "^2.0.1", 100 | "domhandler": "^4.2.0", 101 | "entities": "^2.0.0" 102 | }, 103 | "dependencies": { 104 | "entities": { 105 | "version": "2.2.0", 106 | "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", 107 | "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" 108 | } 109 | } 110 | }, 111 | "domelementtype": { 112 | "version": "2.3.0", 113 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", 114 | "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" 115 | }, 116 | "domhandler": { 117 | "version": "4.3.1", 118 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", 119 | "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", 120 | "requires": { 121 | "domelementtype": "^2.2.0" 122 | } 123 | }, 124 | "domutils": { 125 | "version": "2.8.0", 126 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", 127 | "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", 128 | "requires": { 129 | "dom-serializer": "^1.0.1", 130 | "domelementtype": "^2.2.0", 131 | "domhandler": "^4.2.0" 132 | } 133 | }, 134 | "emoji-regex": { 135 | "version": "6.1.3", 136 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.3.tgz", 137 | "integrity": "sha512-73/zxHTjP2N2FQf0J5ngNjxP9LqG2krUshxYaowI8HxZQsiL2pYJc3k9/O93fc5/lCSkZv+bQ5Esk6k6msiSvg==" 138 | }, 139 | "entities": { 140 | "version": "3.0.1", 141 | "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", 142 | "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" 143 | }, 144 | "escape-string-regexp": { 145 | "version": "4.0.0", 146 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 147 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" 148 | }, 149 | "extend": { 150 | "version": "3.0.2", 151 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 152 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 153 | }, 154 | "fault": { 155 | "version": "1.0.4", 156 | "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", 157 | "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", 158 | "requires": { 159 | "format": "^0.2.0" 160 | } 161 | }, 162 | "format": { 163 | "version": "0.2.2", 164 | "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", 165 | "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" 166 | }, 167 | "htmlparser2": { 168 | "version": "7.2.0", 169 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", 170 | "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", 171 | "requires": { 172 | "domelementtype": "^2.0.1", 173 | "domhandler": "^4.2.2", 174 | "domutils": "^2.8.0", 175 | "entities": "^3.0.1" 176 | } 177 | }, 178 | "is-alphabetical": { 179 | "version": "1.0.4", 180 | "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", 181 | "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" 182 | }, 183 | "is-alphanumerical": { 184 | "version": "1.0.4", 185 | "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", 186 | "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", 187 | "requires": { 188 | "is-alphabetical": "^1.0.0", 189 | "is-decimal": "^1.0.0" 190 | } 191 | }, 192 | "is-buffer": { 193 | "version": "2.0.5", 194 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", 195 | "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" 196 | }, 197 | "is-decimal": { 198 | "version": "1.0.4", 199 | "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", 200 | "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" 201 | }, 202 | "is-hexadecimal": { 203 | "version": "1.0.4", 204 | "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", 205 | "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" 206 | }, 207 | "is-plain-obj": { 208 | "version": "2.1.0", 209 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 210 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" 211 | }, 212 | "longest-streak": { 213 | "version": "2.0.4", 214 | "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", 215 | "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" 216 | }, 217 | "markdown-table": { 218 | "version": "2.0.0", 219 | "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", 220 | "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", 221 | "requires": { 222 | "repeat-string": "^1.0.0" 223 | } 224 | }, 225 | "mdast-util-find-and-replace": { 226 | "version": "1.1.1", 227 | "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", 228 | "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", 229 | "requires": { 230 | "escape-string-regexp": "^4.0.0", 231 | "unist-util-is": "^4.0.0", 232 | "unist-util-visit-parents": "^3.0.0" 233 | } 234 | }, 235 | "mdast-util-footnote": { 236 | "version": "0.1.7", 237 | "resolved": "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz", 238 | "integrity": "sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==", 239 | "requires": { 240 | "mdast-util-to-markdown": "^0.6.0", 241 | "micromark": "~2.11.0" 242 | } 243 | }, 244 | "mdast-util-from-markdown": { 245 | "version": "0.8.5", 246 | "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", 247 | "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", 248 | "requires": { 249 | "@types/mdast": "^3.0.0", 250 | "mdast-util-to-string": "^2.0.0", 251 | "micromark": "~2.11.0", 252 | "parse-entities": "^2.0.0", 253 | "unist-util-stringify-position": "^2.0.0" 254 | } 255 | }, 256 | "mdast-util-frontmatter": { 257 | "version": "0.2.0", 258 | "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz", 259 | "integrity": "sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==", 260 | "requires": { 261 | "micromark-extension-frontmatter": "^0.2.0" 262 | } 263 | }, 264 | "mdast-util-gfm": { 265 | "version": "0.1.2", 266 | "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", 267 | "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", 268 | "requires": { 269 | "mdast-util-gfm-autolink-literal": "^0.1.0", 270 | "mdast-util-gfm-strikethrough": "^0.2.0", 271 | "mdast-util-gfm-table": "^0.1.0", 272 | "mdast-util-gfm-task-list-item": "^0.1.0", 273 | "mdast-util-to-markdown": "^0.6.1" 274 | } 275 | }, 276 | "mdast-util-gfm-autolink-literal": { 277 | "version": "0.1.3", 278 | "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", 279 | "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", 280 | "requires": { 281 | "ccount": "^1.0.0", 282 | "mdast-util-find-and-replace": "^1.1.0", 283 | "micromark": "^2.11.3" 284 | } 285 | }, 286 | "mdast-util-gfm-strikethrough": { 287 | "version": "0.2.3", 288 | "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", 289 | "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", 290 | "requires": { 291 | "mdast-util-to-markdown": "^0.6.0" 292 | } 293 | }, 294 | "mdast-util-gfm-table": { 295 | "version": "0.1.6", 296 | "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", 297 | "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", 298 | "requires": { 299 | "markdown-table": "^2.0.0", 300 | "mdast-util-to-markdown": "~0.6.0" 301 | } 302 | }, 303 | "mdast-util-gfm-task-list-item": { 304 | "version": "0.1.6", 305 | "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", 306 | "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", 307 | "requires": { 308 | "mdast-util-to-markdown": "~0.6.0" 309 | } 310 | }, 311 | "mdast-util-to-markdown": { 312 | "version": "0.6.5", 313 | "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", 314 | "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", 315 | "requires": { 316 | "@types/unist": "^2.0.0", 317 | "longest-streak": "^2.0.0", 318 | "mdast-util-to-string": "^2.0.0", 319 | "parse-entities": "^2.0.0", 320 | "repeat-string": "^1.0.0", 321 | "zwitch": "^1.0.0" 322 | } 323 | }, 324 | "mdast-util-to-string": { 325 | "version": "2.0.0", 326 | "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", 327 | "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" 328 | }, 329 | "micromark": { 330 | "version": "2.11.4", 331 | "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", 332 | "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", 333 | "requires": { 334 | "debug": "^4.0.0", 335 | "parse-entities": "^2.0.0" 336 | } 337 | }, 338 | "micromark-extension-footnote": { 339 | "version": "0.3.2", 340 | "resolved": "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz", 341 | "integrity": "sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==", 342 | "requires": { 343 | "micromark": "~2.11.0" 344 | } 345 | }, 346 | "micromark-extension-frontmatter": { 347 | "version": "0.2.2", 348 | "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz", 349 | "integrity": "sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==", 350 | "requires": { 351 | "fault": "^1.0.0" 352 | } 353 | }, 354 | "micromark-extension-gfm": { 355 | "version": "0.3.3", 356 | "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", 357 | "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", 358 | "requires": { 359 | "micromark": "~2.11.0", 360 | "micromark-extension-gfm-autolink-literal": "~0.5.0", 361 | "micromark-extension-gfm-strikethrough": "~0.6.5", 362 | "micromark-extension-gfm-table": "~0.4.0", 363 | "micromark-extension-gfm-tagfilter": "~0.3.0", 364 | "micromark-extension-gfm-task-list-item": "~0.3.0" 365 | } 366 | }, 367 | "micromark-extension-gfm-autolink-literal": { 368 | "version": "0.5.7", 369 | "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", 370 | "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", 371 | "requires": { 372 | "micromark": "~2.11.3" 373 | } 374 | }, 375 | "micromark-extension-gfm-strikethrough": { 376 | "version": "0.6.5", 377 | "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", 378 | "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", 379 | "requires": { 380 | "micromark": "~2.11.0" 381 | } 382 | }, 383 | "micromark-extension-gfm-table": { 384 | "version": "0.4.3", 385 | "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", 386 | "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", 387 | "requires": { 388 | "micromark": "~2.11.0" 389 | } 390 | }, 391 | "micromark-extension-gfm-tagfilter": { 392 | "version": "0.3.0", 393 | "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", 394 | "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==" 395 | }, 396 | "micromark-extension-gfm-task-list-item": { 397 | "version": "0.3.3", 398 | "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", 399 | "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", 400 | "requires": { 401 | "micromark": "~2.11.0" 402 | } 403 | }, 404 | "minimist": { 405 | "version": "1.2.6", 406 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 407 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" 408 | }, 409 | "ms": { 410 | "version": "2.1.2", 411 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 412 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 413 | }, 414 | "parse-entities": { 415 | "version": "2.0.0", 416 | "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", 417 | "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", 418 | "requires": { 419 | "character-entities": "^1.0.0", 420 | "character-entities-legacy": "^1.0.0", 421 | "character-reference-invalid": "^1.0.0", 422 | "is-alphanumerical": "^1.0.0", 423 | "is-decimal": "^1.0.0", 424 | "is-hexadecimal": "^1.0.0" 425 | } 426 | }, 427 | "remark-footnotes": { 428 | "version": "3.0.0", 429 | "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz", 430 | "integrity": "sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==", 431 | "requires": { 432 | "mdast-util-footnote": "^0.1.0", 433 | "micromark-extension-footnote": "^0.3.0" 434 | } 435 | }, 436 | "remark-frontmatter": { 437 | "version": "3.0.0", 438 | "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz", 439 | "integrity": "sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==", 440 | "requires": { 441 | "mdast-util-frontmatter": "^0.2.0", 442 | "micromark-extension-frontmatter": "^0.2.0" 443 | } 444 | }, 445 | "remark-gfm": { 446 | "version": "1.0.0", 447 | "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", 448 | "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", 449 | "requires": { 450 | "mdast-util-gfm": "^0.1.0", 451 | "micromark-extension-gfm": "^0.3.0" 452 | } 453 | }, 454 | "remark-parse": { 455 | "version": "9.0.0", 456 | "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", 457 | "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", 458 | "requires": { 459 | "mdast-util-from-markdown": "^0.8.0" 460 | } 461 | }, 462 | "repeat-string": { 463 | "version": "1.6.1", 464 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 465 | "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" 466 | }, 467 | "traverse": { 468 | "version": "0.6.6", 469 | "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", 470 | "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" 471 | }, 472 | "trough": { 473 | "version": "1.0.5", 474 | "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", 475 | "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" 476 | }, 477 | "underscore": { 478 | "version": "1.13.4", 479 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz", 480 | "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==" 481 | }, 482 | "unified": { 483 | "version": "9.2.2", 484 | "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", 485 | "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", 486 | "requires": { 487 | "bail": "^1.0.0", 488 | "extend": "^3.0.0", 489 | "is-buffer": "^2.0.0", 490 | "is-plain-obj": "^2.0.0", 491 | "trough": "^1.0.0", 492 | "vfile": "^4.0.0" 493 | } 494 | }, 495 | "unist-util-is": { 496 | "version": "4.1.0", 497 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", 498 | "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" 499 | }, 500 | "unist-util-stringify-position": { 501 | "version": "2.0.3", 502 | "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", 503 | "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", 504 | "requires": { 505 | "@types/unist": "^2.0.2" 506 | } 507 | }, 508 | "unist-util-visit-parents": { 509 | "version": "3.1.1", 510 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", 511 | "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", 512 | "requires": { 513 | "@types/unist": "^2.0.0", 514 | "unist-util-is": "^4.0.0" 515 | } 516 | }, 517 | "update-section": { 518 | "version": "0.3.3", 519 | "resolved": "https://registry.npmjs.org/update-section/-/update-section-0.3.3.tgz", 520 | "integrity": "sha512-BpRZMZpgXLuTiKeiu7kK0nIPwGdyrqrs6EDSaXtjD/aQ2T+qVo9a5hRC3HN3iJjCMxNT/VxoLGQ7E/OzE5ucnw==" 521 | }, 522 | "vfile": { 523 | "version": "4.2.1", 524 | "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", 525 | "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", 526 | "requires": { 527 | "@types/unist": "^2.0.0", 528 | "is-buffer": "^2.0.0", 529 | "unist-util-stringify-position": "^2.0.0", 530 | "vfile-message": "^2.0.0" 531 | } 532 | }, 533 | "vfile-message": { 534 | "version": "2.0.4", 535 | "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", 536 | "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", 537 | "requires": { 538 | "@types/unist": "^2.0.0", 539 | "unist-util-stringify-position": "^2.0.0" 540 | } 541 | }, 542 | "zwitch": { 543 | "version": "1.0.5", 544 | "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", 545 | "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" 546 | } 547 | } 548 | } 549 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cost-optimization", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git@github.sup.team:Startup-Samples/cost-optimization.git" 12 | }, 13 | "author": "", 14 | "license": "MIT", 15 | "dependencies": { 16 | "doctoc": "^2.2.0" 17 | } 18 | } 19 | --------------------------------------------------------------------------------