Pull to refresh

Comments 8

«Помимо Billing Dashboard, соседний Cost Explorer.»
Прекрасный перевод…
+1 — мне тоже кажется что такие вещи можно сделать без кода
Прежде чем начать работать, надо познакомиться со стандартным видом консоли Billing Dashboard. Нужно сначала включить её, что будет стоить денег.

Хотите узнать куда уходят ваши денежки? Сначала заплатите!
UFO landed and left these words here
Sign up to leave a comment.

Articles

:float(v['Total']['NetRISavings'])})\n else:\n row.update({'Utilization%':float(v['Total']['UtilizationPercentage'])})\n rows.append(row) \n\n df = pd.DataFrame(rows)\n df.set_index(\"date\", inplace= True)\n df = df.fillna(0.0)\n df = df.T\n type = 'chart'\n else:\n df = pd.DataFrame(rows)\n type = 'table' #Dont try chart empty result\n elif Name == 'RIRecommendation':\n results = []\n response = self.client.get_reservation_purchase_recommendation(\n #AccountId='string', May use for Linked view\n LookbackPeriodInDays='SIXTY_DAYS',\n TermInYears='ONE_YEAR',\n PaymentOption=PaymentOption,\n Service=Service\n )\n results.extend(response['Recommendations'])\n while 'nextToken' in response:\n nextToken = response['nextToken']\n response = self.client.get_reservation_purchase_recommendation(\n #AccountId='string', May use for Linked view\n LookbackPeriodInDays='SIXTY_DAYS',\n TermInYears='ONE_YEAR',\n PaymentOption=PaymentOption,\n Service=Service,\n NextPageToken=nextToken\n )\n results.extend(response['Recommendations'])\n if 'nextToken' in response:\n nextToken = response['nextToken']\n else:\n nextToken = False\n\n rows = []\n for i in results:\n for v in i['RecommendationDetails']:\n row = v['InstanceDetails'][list(v['InstanceDetails'].keys())[0]]\n row['Recommended']=v['RecommendedNumberOfInstancesToPurchase']\n row['Minimum']=v['MinimumNumberOfInstancesUsedPerHour']\n row['Maximum']=v['MaximumNumberOfInstancesUsedPerHour']\n row['Savings']=v['EstimatedMonthlySavingsAmount']\n row['OnDemand']=v['EstimatedMonthlyOnDemandCost']\n row['BreakEvenIn']=v['EstimatedBreakEvenInMonths']\n row['UpfrontCost']=v['UpfrontCost']\n row['MonthlyCost']=v['RecurringStandardMonthlyCost']\n rows.append(row) \n\n\n df = pd.DataFrame(rows)\n df = df.fillna(0.0)\n type = 'table' #Dont try chart this\n self.reports.append({'Name':Name,'Data':df, 'Type':type})\n\n\n def addReport(self, Name=\"Default\",GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"SERVICE\"},], \n Style='Total', NoCredits=True, CreditsOnly=False, RefundOnly=False, UpfrontOnly=False, IncSupport=False):\n type = 'chart' #other option table\n results = []\n if not NoCredits:\n response = self.client.get_cost_and_usage(\n TimePeriod={\n 'Start': self.start.isoformat(),\n 'End': self.end.isoformat()\n },\n Granularity='MONTHLY',\n Metrics=[\n 'UnblendedCost',\n ],\n GroupBy=GroupBy\n )\n else:\n Filter = {\"And\": []}\n\n Dimensions={\"Not\": {\"Dimensions\": {\"Key\": \"RECORD_TYPE\",\"Values\": [\"Credit\", \"Refund\", \"Upfront\", \"Support\"]}}}\n if INC_SUPPORT or IncSupport: #If global set for including support, we dont exclude it\n Dimensions={\"Not\": {\"Dimensions\": {\"Key\": \"RECORD_TYPE\",\"Values\": [\"Credit\", \"Refund\", \"Upfront\"]}}}\n if CreditsOnly:\n Dimensions={\"Dimensions\": {\"Key\": \"RECORD_TYPE\",\"Values\": [\"Credit\",]}}\n if RefundOnly:\n Dimensions={\"Dimensions\": {\"Key\": \"RECORD_TYPE\",\"Values\": [\"Refund\",]}}\n if UpfrontOnly:\n Dimensions={\"Dimensions\": {\"Key\": \"RECORD_TYPE\",\"Values\": [\"Upfront\",]}}\n\n tagValues = None\n if TAG_KEY:\n tagValues = self.client.get_tags(\n SearchString=TAG_VALUE_FILTER,\n TimePeriod = {\n 'Start': self.start.isoformat(),\n 'End': datetime.date.today().isoformat()\n },\n TagKey=TAG_KEY\n )\n\n if tagValues:\n Filter[\"And\"].append(Dimensions)\n if len(tagValues[\"Tags\"]) > 0:\n Tags = {\"Tags\": {\"Key\": TAG_KEY, \"Values\": tagValues[\"Tags\"]}}\n Filter[\"And\"].append(Tags)\n else:\n Filter = Dimensions.copy()\n\n response = self.client.get_cost_and_usage(\n TimePeriod={\n 'Start': self.start.isoformat(),\n 'End': self.end.isoformat()\n },\n Granularity='MONTHLY',\n Metrics=[\n 'UnblendedCost',\n ],\n GroupBy=GroupBy,\n Filter=Filter\n )\n\n if response:\n results.extend(response['ResultsByTime'])\n\n while 'nextToken' in response:\n nextToken = response['nextToken']\n response = self.client.get_cost_and_usage(\n TimePeriod={\n 'Start': self.start.isoformat(),\n 'End': self.end.isoformat()\n },\n Granularity='MONTHLY',\n Metrics=[\n 'UnblendedCost',\n ],\n GroupBy=GroupBy,\n NextPageToken=nextToken\n )\n\n results.extend(response['ResultsByTime'])\n if 'nextToken' in response:\n nextToken = response['nextToken']\n else:\n nextToken = False\n rows = []\n sort = ''\n for v in results:\n row = {'date':v['TimePeriod']['Start']}\n sort = v['TimePeriod']['Start']\n for i in v['Groups']:\n key = i['Keys'][0]\n if key in self.accounts:\n key = self.accounts[key][ACCOUNT_LABEL]\n row.update({key:float(i['Metrics']['UnblendedCost']['Amount'])}) \n if not v['Groups']:\n row.update({'Total':float(v['Total']['UnblendedCost']['Amount'])})\n rows.append(row) \n\n df = pd.DataFrame(rows)\n df.set_index(\"date\", inplace= True)\n df = df.fillna(0.0)\n\n if Style == 'Change':\n dfc = df.copy()\n lastindex = None\n for index, row in df.iterrows():\n if lastindex:\n for i in row.index:\n try:\n df.at[index,i] = dfc.at[index,i] - dfc.at[lastindex,i]\n except:\n logging.exception(\"Error\")\n df.at[index,i] = 0\n lastindex = index\n df = df.T\n df = df.sort_values(sort, ascending=False)\n self.reports.append({'Name':Name,'Data':df, 'Type':type})\n\n\n def generateExcel(self):\n # Create a Pandas Excel writer using XlsxWriter as the engine.\\\n os.chdir('\u002Ftmp')\n writer = pd.ExcelWriter('cost_explorer_report.xlsx', engine='xlsxwriter')\n workbook = writer.book\n for report in self.reports:\n print(report['Name'],report['Type'])\n report['Data'].to_excel(writer, sheet_name=report['Name'])\n worksheet = writer.sheets[report['Name']]\n if report['Type'] == 'chart':\n\n # Create a chart object.\n chart = workbook.add_chart({'type': 'column', 'subtype': 'stacked'})\n\n\n chartend=13\n for row_num in range(1, len(report['Data']) + 1):\n chart.add_series({\n 'name': [report['Name'], row_num, 0],\n 'categories': [report['Name'], 0, 1, 0, chartend],\n 'values': [report['Name'], row_num, 1, row_num, chartend],\n })\n chart.set_y_axis({'label_position': 'low'})\n chart.set_x_axis({'label_position': 'low'})\n worksheet.insert_chart('O2', chart, {'x_scale': 2.0, 'y_scale': 2.0})\n writer.save()\n\n #Time to deliver the file to S3\n if os.environ.get('S3_BUCKET'):\n s3 = boto3.client('s3')\n s3.upload_file(\"cost_explorer_report.xlsx\", os.environ.get('S3_BUCKET'), \"cost_explorer_report.xlsx\")\n if os.environ.get('SES_SEND'):\n #Email logic\n msg = MIMEMultipart()\n msg['From'] = os.environ.get('SES_FROM')\n msg['To'] = COMMASPACE.join(os.environ.get('SES_SEND').split(\",\"))\n msg['Date'] = formatdate(localtime=True)\n msg['Subject'] = \"Cost Explorer Report\"\n text = \"Find your Cost Explorer report attached\\n\\n\"\n msg.attach(MIMEText(text))\n with open(\"cost_explorer_report.xlsx\", \"rb\") as fil:\n part = MIMEApplication(\n fil.read(),\n Name=\"cost_explorer_report.xlsx\"\n )\n part['Content-Disposition'] = 'attachment; filename=\"%s\"' % \"cost_explorer_report.xlsx\"\n msg.attach(part)\n #SES Sending\n ses = boto3.client('ses', region_name=SES_REGION)\n result = ses.send_raw_email(\n Source=msg['From'],\n Destinations=os.environ.get('SES_SEND').split(\",\"),\n RawMessage={'Data': msg.as_string()}\n ) \n\n\ndef lambda_handler(event, context):\n costexplorer = CostExplorer(CurrentMonth=False)\n #Default addReport has filter to remove Support \u002F Credits \u002F Refunds \u002F UpfrontRI\n #Overall Billing Reports\n costexplorer.addReport(Name=\"Total\", GroupBy=[],Style='Total',IncSupport=True)\n costexplorer.addReport(Name=\"TotalChange\", GroupBy=[],Style='Change')\n costexplorer.addReport(Name=\"TotalInclCredits\", GroupBy=[],Style='Total',NoCredits=False,IncSupport=True)\n costexplorer.addReport(Name=\"TotalInclCreditsChange\", GroupBy=[],Style='Change',NoCredits=False)\n costexplorer.addReport(Name=\"Credits\", GroupBy=[],Style='Total',CreditsOnly=True)\n costexplorer.addReport(Name=\"Refunds\", GroupBy=[],Style='Total',RefundOnly=True)\n costexplorer.addReport(Name=\"RIUpfront\", GroupBy=[],Style='Total',UpfrontOnly=True)\n #GroupBy Reports\n costexplorer.addReport(Name=\"Services\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"SERVICE\"}],Style='Total',IncSupport=True)\n costexplorer.addReport(Name=\"ServicesChange\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"SERVICE\"}],Style='Change')\n costexplorer.addReport(Name=\"Accounts\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"LINKED_ACCOUNT\"}],Style='Total')\n costexplorer.addReport(Name=\"AccountsChange\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"LINKED_ACCOUNT\"}],Style='Change')\n costexplorer.addReport(Name=\"Regions\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"REGION\"}],Style='Total')\n costexplorer.addReport(Name=\"RegionsChange\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"REGION\"}],Style='Change')\n if os.environ.get('COST_TAGS'): #Support for multiple\u002Fdifferent Cost Allocation tags\n for tagkey in os.environ.get('COST_TAGS').split(','):\n tabname = tagkey.replace(\":\",\".\") #Remove special chars from Excel tabname\n costexplorer.addReport(Name=\"{}\".format(tabname)[:31], GroupBy=[{\"Type\": \"TAG\",\"Key\": tagkey}],Style='Total')\n costexplorer.addReport(Name=\"Change-{}\".format(tabname)[:31], GroupBy=[{\"Type\": \"TAG\",\"Key\": tagkey}],Style='Change')\n #RI Reports\n costexplorer.addRiReport(Name=\"RICoverage\")\n costexplorer.addRiReport(Name=\"RIUtilization\")\n costexplorer.addRiReport(Name=\"RIUtilizationSavings\", Savings=True)\n costexplorer.addRiReport(Name=\"RIRecommendation\") #Service supported value(s): Amazon Elastic Compute Cloud - Compute, Amazon Relational Database Service\n costexplorer.generateExcel()\n return \"Report Generated\"\n\u003C\u002Fcode\u003E\u003Cdiv class=\"code-explainer\"\u003E\u003Ca href=\"https:\u002F\u002Fsourcecraft.dev\u002F\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"\u003E\u003Cimg style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003C\u002Fpre\u003E\u003Ch2\u003EIAM Role\u003C\u002Fh2\u003E\u003Cp\u003EЧтобы запускаться, Lambda функция должна обладать ролью с приведенными ниже правами:\u003C\u002Fp\u003E\u003Ch3\u003EБазовая политика Lambda\u003C\u002Fh3\u003E\u003Cpre\u003E\u003Ccode class=\"json\"\u003E{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"logs:CreateLogGroup\",\n \"logs:CreateLogStream\",\n \"logs:PutLogEvents\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}\u003C\u002Fcode\u003E\u003Cdiv class=\"code-explainer\"\u003E\u003Ca href=\"https:\u002F\u002Fsourcecraft.dev\u002F\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"\u003E\u003Cimg style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003C\u002Fpre\u003E\u003Ch3\u003EРазрешение для записи отчетов в S3 бакет\u003C\u002Fh3\u003E\u003Cpre\u003E\u003Ccode class=\"json\"\u003E{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:PutObject\",\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::account.admin\u002F*\"\n }\n ]\n}\u003C\u002Fcode\u003E\u003Cdiv class=\"code-explainer\"\u003E\u003Ca href=\"https:\u002F\u002Fsourcecraft.dev\u002F\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"\u003E\u003Cimg style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003C\u002Fpre\u003E\u003Ch3\u003ESimple Email Service\u003C\u002Fh3\u003E\u003Cpre\u003E\u003Ccode class=\"json\"\u003E{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ses:SendEmail\",\n \"ses:SendRawEmail\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}\u003C\u002Fcode\u003E\u003Cdiv class=\"code-explainer\"\u003E\u003Ca href=\"https:\u002F\u002Fsourcecraft.dev\u002F\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"\u003E\u003Cimg style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003C\u002Fpre\u003E\u003Ch3\u003ECost Explorer\u003C\u002Fh3\u003E\u003Cpre\u003E\u003Ccode class=\"json\"\u003E{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": \"ce:*\",\n \"Resource\": \"*\"\n }\n ]\n}\u003C\u002Fcode\u003E\u003Cdiv class=\"code-explainer\"\u003E\u003Ca href=\"https:\u002F\u002Fsourcecraft.dev\u002F\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"\u003E\u003Cimg style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003C\u002Fpre\u003E\u003Ch2\u003EЗапуск на Event Bridge\u003C\u002Fh2\u003E\u003Cp\u003EНаконец, мы настраиваем регулярный запуск нашей Lambda функции на Event Bridge, например, 5 числа каждого месяца. В результате работы всех настроек я буду получать email с прикрепленным XLS-отчетом. Также можно настраивать срабатывание еженедельно и даже на определенные дни недели, при необходимости.\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E","tags":[{"titleHtml":"aws"},{"titleHtml":"lambda"},{"titleHtml":"serverless"},{"titleHtml":"api"},{"titleHtml":"costs"},{"titleHtml":"billing"},{"titleHtml":"ses"},{"titleHtml":"s3"},{"titleHtml":"amazon s3"},{"titleHtml":"amazon ec2"}],"metadata":{"stylesUrls":[],"scriptUrls":[],"shareImageUrl":"https:\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fupload_files\u002F568\u002Ff14\u002Faed\u002F568f14aeda6d5551717124a19f23fe2c.png","shareImageWidth":1200,"shareImageHeight":630,"vkShareImageUrl":"https:\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fupload_files\u002F568\u002Ff14\u002Faed\u002F568f14aeda6d5551717124a19f23fe2c.png","schemaJsonLd":"{\"@context\":\"http:\\\u002F\\\u002Fschema.org\",\"@type\":\"Article\",\"mainEntityOfPage\":{\"@type\":\"WebPage\",\"@id\":\"https:\\\u002F\\\u002Fhabr.com\\\u002Fru\\\u002Farticles\\\u002F552462\\\u002F\"},\"headline\":\"Оптимизируем затраты с помощью AWS Cost Explorer\",\"datePublished\":\"2021-04-15T14:08:28+03:00\",\"dateModified\":\"2021-04-15T14:50:19+03:00\",\"author\":{\"@type\":\"Person\",\"name\":\"Михаил Соколов\"},\"publisher\":{\"@type\":\"Organization\",\"name\":\"Habr\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\u002F\\\u002Fhabrastorage.org\\\u002Fwebt\\\u002Fa_\\\u002Flk\\\u002F9m\\\u002Fa_lk9mjkccjox-zccjrpfolmkmq.png\"}},\"description\":\"У Amazon Web Services отличный бесплатный пакет: хороший набор сервисов и щедрая раздача кредитов для разработчиков. Я был уверен: проблем с оплатой моего окруже...\",\"url\":\"https:\\\u002F\\\u002Fhabr.com\\\u002Fru\\\u002Farticles\\\u002F552462\\\u002F#post-content-body\",\"about\":[\"h_python\",\"h_cloud_computing\",\"h_aws\",\"h_api\",\"h_serverless\",\"f_develop\",\"f_admin\"],\"image\":[\"https:\\\u002F\\\u002Fhabr.com\\\u002Fshare\\\u002Fpublication\\\u002F552462\\\u002F9c327c38bc313537925dccf2ffe412b9\\\u002F\",\"https:\\\u002F\\\u002Fhabrastorage.org\\\u002Fgetpro\\\u002Fhabr\\\u002Fupload_files\\\u002F568\\\u002Ff14\\\u002Faed\\\u002F568f14aeda6d5551717124a19f23fe2c.png\",\"https:\\\u002F\\\u002Fhabrastorage.org\\\u002Fgetpro\\\u002Fhabr\\\u002Fupload_files\\\u002F2ee\\\u002Ff02\\\u002Faf1\\\u002F2eef02af1ec14ba13af3479c20e38f63.png\",\"https:\\\u002F\\\u002Fhabrastorage.org\\\u002Fgetpro\\\u002Fhabr\\\u002Fupload_files\\\u002F549\\\u002F259\\\u002Fbbb\\\u002F549259bbb0e6051d00b44b0ff3dd005c.png\"]}","metaDescription":"У Amazon Web Services отличный бесплатный пакет: хороший набор сервисов и щедрая раздача кредитов для разработчиков. Я был уверен: проблем с оплатой моего окружения не будет, поэтому о расходах...","mainImageUrl":null,"amp":true,"customTrackerLinks":[]},"polls":[],"commentsEnabled":{"status":true,"reason":null},"rulesRemindEnabled":false,"votesEnabled":true,"status":"published","plannedPublishTime":null,"checked":null,"hasPinnedComments":false,"format":"tutorial","banner":null,"multiwidget":null,"multiwidgetUuid":null,"readingTime":11,"complexity":null,"isEditorial":false,"flowNew":null,"linkedPostTranslation":null,"hasRegionalRestrictions":false}},"articlesIds":{},"isLoading":false,"pagesCount":{},"route":{},"reasonsList":null,"postReasonsList":null,"view":"cards","oldEditorForm":null,"lastVisitedRoute":{},"ssrCommentsArticleIds":[],"viewedPosts":[],"myFeedFilter":{"complexity":"all","score":"all","types":["articles","posts","news"]},"myFeedIsApplyFilters":false,"myFeedIsForce":false},"me":{"user":null,"uuid":null,"ppgDemanded":false,"karmaResetInfo":{"canReincarnate":null,"wasReincarnated":null,"currentScore":null},"notes":null,"userUpdates":{"feeds":{"newCount":null},"conversationUnreadCount":0,"trackerUnreadCount":0},"features":null},"flowsMenu":{"flowsMenuData":{"whatsNew":{"newAuthors":{"order":7,"items":[{"alias":"Paulik8","fullname":"Paulik8","avatarUrl":null},{"alias":"xeovo","fullname":"xeovo","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002Fe83\u002Fde8\u002Ff9e\u002Fe83de8f9ed182d9287ca9900d263c2f9.png"},{"alias":"v_pyatnitsky","fullname":"v_pyatnitsky","avatarUrl":null},{"alias":"Eroric","fullname":"Егор","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002F5be\u002Fb62\u002F2cc\u002F5beb622cca3684ec4e6e1d65db09e33b.jpeg"},{"alias":"i_alakey","fullname":"Alakov Ilia","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002Fb17\u002F2fb\u002F11a\u002Fb172fb11a63957a6e68e8512932fb851.jpeg"},{"alias":"Blaukovitch","fullname":"Max S.","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002F130\u002F274\u002Fd34\u002F130274d3415c6b38a647c7f3ee50b57b.gif"},{"alias":"opintery","fullname":"opintery","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002F4da\u002F0cd\u002F631\u002F4da0cd631114bdab1667531bd8b9e4e2.jpeg"},{"alias":"emishkurov","fullname":"Эдуард Мишкуров","avatarUrl":null}]},"updates":{"order":8,"items":[{"title":"Changelog","url":"https:\u002F\u002Fhabr.com\u002Fen\u002Fdocs\u002Fchangelog\u002F2025\u002F","imageUrl":null},{"title":"Habr Code of Authors","url":"https:\u002F\u002Fhabr.com\u002Fen\u002Fdocs\u002Fauthors\u002Fcodex\u002F","imageUrl":null},{"title":"How it works","url":"https:\u002F\u002Fhabr.com\u002Fen\u002Fdocs\u002Fhelp\u002Frules\u002F","imageUrl":null},{"title":"Corporate blogs","url":"https:\u002F\u002Fhabr.com\u002Fen\u002Fdocs\u002Fcompanies\u002Fcorpblogs\u002F","imageUrl":null}]},"socialNetwork":{"order":1},"thematicChannels":{"order":3},"ourActivities":{"order":4},"partnersActivities":{"order":5},"banner":{"order":6},"ourBlogs":{"order":2}},"flows":{"backend":{"technologies":{"order":1,"items":[{"alias":"postgresql","title":"PostgreSQL","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F391\u002F633\u002F8e2\u002F3916338e24104572809b971807686a8f.png"},{"alias":"sql","title":"SQL","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F64b\u002F22b\u002F8b6\u002F64b22b8b6c4677778423e971d52eb05d.png"},{"alias":"oracle","title":"Oracle","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002Fc9d\u002F1a4\u002Fb6f\u002Fc9d1a4b6f8257d96fbecc20a2efa199c.png"}]},"topics":{"order":2,"items":[]},"topPosts":{"order":3,"items":[],"period":"day"},"topAuthors":{"order":4,"items":[{"alias":"kaze_no_saga","fullname":"Александр Мелешко","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002Fdcc\u002F532\u002Ff26\u002Fdcc532f26204fdcf8498d744aefac55d.jpg"},{"alias":"melanny20","fullname":"Мила","avatarUrl":null}]},"topCompanies":{"order":5,"items":[]},"banner":{"order":6}},"ai_and_ml":{"technologies":{"order":1,"items":[]},"topics":{"order":2,"items":[{"alias":"artificial_intelligence","title":"Artificial Intelligence","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002Ff01\u002F3a4\u002F009\u002Ff013a40094ae05299b2b05ef05e7f981.png"}]},"topPosts":{"order":3,"items":[],"period":"day"},"topAuthors":{"order":4,"items":[{"alias":"v_pyatnitsky","fullname":"v_pyatnitsky","avatarUrl":null}]},"topCompanies":{"order":5,"items":[]},"banner":{"order":6}},"information_security":{"technologies":{"order":1,"items":[{"alias":"go","title":"Go","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002Fa10\u002Fc5c\u002F626\u002Fa10c5c62685d9a7d2964993daf6958c3.png"},{"alias":"win_dev","title":"Development for Windows","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F303\u002F8bf\u002F46a\u002F3038bf46a77eed6f51b84c8a9cf87076.png"}]},"topics":{"order":2,"items":[{"alias":"business-laws","title":"Legislation in IT","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F7e3\u002Ffbd\u002F404\u002F7e3fbd40404e7a51fafad53018d606c8.png"},{"alias":"hosting","title":"Hosting","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F270\u002Ffae\u002F79d\u002F270fae79d4cd7070a1bcc27f41f68ce6.png"},{"alias":"infosecurity","title":"Information Security","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F135\u002F2db\u002F187\u002F1352db18765addaa6e0b2ac013d386d8.png"},{"alias":"it-infrastructure","title":"IT Infrastructure","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F594\u002F546\u002F45b\u002F59454645b38d9a58a92e6870133ae8e6.png"},{"alias":"network_technologies","title":"Network technologies","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002Fb2e\u002F13f\u002F8fc\u002Fb2e13f8fcaf2711677c87418b98e85fe.png"},{"alias":"s_admin","title":"Server Administration","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F1b7\u002F37e\u002F2d9\u002F1b737e2d9b2f7b60a2f5700eb5f93f1e.png"}]},"topPosts":{"order":3,"items":[],"period":"day"},"topAuthors":{"order":4,"items":[{"alias":"xeovo","fullname":"xeovo","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002Fe83\u002Fde8\u002Ff9e\u002Fe83de8f9ed182d9287ca9900d263c2f9.png"}]},"topCompanies":{"order":5,"items":[{"alias":"xeovo","title":"Xeovo VPN","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fcompany\u002F864\u002F431\u002F196\u002F864431196b8a78de320f5707f6d8ff33.png"}]},"banner":{"order":6}},"mobile_development":{"technologies":{"order":1,"items":[{"alias":"dart","title":"Dart","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F41e\u002F671\u002F2dd\u002F41e6712dd7d298077553efff8562bd73.png"},{"alias":"flutter","title":"Flutter","imageUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Fhub\u002F63b\u002F728\u002Fb76\u002F63b728b76ec18862a5454a684509940b.png"}]},"topics":{"order":2,"items":[]},"topPosts":{"order":3,"items":[],"period":"day"},"topAuthors":{"order":4,"items":[{"alias":"Paulik8","fullname":"Paulik8","avatarUrl":null}]},"topCompanies":{"order":5,"items":[]},"banner":{"order":6}}},"events":{"items":[]}},"isMenuVisible":false},"banner":{"isArticleStickyPanelVisible":false,"isArticleStickyPanelAtTheBottom":false,"bannerContainer":null,"isHeaderBannerInView":true,"isSponsorBlockPresent":false,"isHeaderBannerVisible":true,"isPBrandingVisible":false},"refs":{"flowsRefs":[{"id":"2","title":"Бэкенд","alias":"backend"},{"id":"4","title":"Фронтенд","alias":"frontend"},{"id":"6","title":"Мобильная разработка","alias":"mobile_development"},{"id":"8","title":"Системное администрирование","alias":"admin"},{"id":"10","title":"Информационная безопасность","alias":"information_security"},{"id":"12","title":"AI и ML","alias":"ai_and_ml"},{"id":"14","title":"Промышленная инженерия","alias":"industrial_engineering"},{"id":"16","title":"Геймдев","alias":"gamedev"},{"id":"18","title":"Тестирование","alias":"quality_assurance"},{"id":"20","title":"Техническая поддержка","alias":"support"},{"id":"22","title":"Системный и бизнес-анализ","alias":"analytics"},{"id":"24","title":"Дизайн","alias":"design"},{"id":"26","title":"Менеджмент","alias":"management"},{"id":"28","title":"Топ-менеджмент","alias":"top_management"},{"id":"30","title":"Маркетинг и контент","alias":"marketing"},{"id":"34","title":"Продажи","alias":"sales"},{"id":"36","title":"HR","alias":"human_resources"},{"id":"38","title":"Бэк-офис","alias":"back_office"},{"id":"40","title":"Зерокодинг","alias":"zero-code_development"},{"id":"42","title":"Железо и гаджеты","alias":"hardware_and_gadgets"},{"id":"44","title":"DIY","alias":"diy"},{"id":"46","title":"Здоровье","alias":"healthcare"},{"id":"48","title":"Научпоп","alias":"popsci"},{"id":"50","title":"Другое","alias":"other"}]},"promoData":{"isLoading":false,"hasLoaded":false,"featurer":null,"megaposts":null,"promoLinks":null,"promoPosts":null,"sticker":null,"stories":null,"activities":[],"partnerActivities":[],"isPromoDataAvailable":{"featurer":true,"promoPosts":true,"promoLinks":false,"megaposts":false}},"fixedBanner":{"isLoading":false,"viewEventsSent":[],"viewMRCEventsSent":[],"imagesLoaded":{}},"companies":{"companyRefs":{"__ALIAS_STORE__":true},"companyIds":{},"companyTopIds":[],"companyRouteStatistics":{},"pagesCount":{},"companyProfiles":{"__ALIAS_STORE__":true},"companiesCategories":[],"companiesCategoriesTotalCount":0,"companiesWidgets":{"__ALIAS_STORE__":true},"companiesWorkers":{"__ALIAS_STORE__":true},"companiesFans":{"__ALIAS_STORE__":true},"multiwidgets":{"__ALIAS_STORE__":true},"route":{},"isLoading":false,"companyWorkersLoading":false,"companyFansLoading":false,"multiwidgetLoading":false,"vacancies":{},"companiesGalleries":{"__ALIAS_STORE__":true},"companiesBanners":{"__ALIAS_STORE__":true},"companiesLandingVacancies":{"__ALIAS_STORE__":true},"companiesTechnologies":{"__ALIAS_STORE__":true},"workplaceInfo":null},"ssr":{"error":null,"isDataLoaded":true,"isDataLoading":false},"hubs":{"hubRefs":{"__ALIAS_STORE__":true},"hubIds":{},"hubRouteStats":{},"pagesCount":{},"isLoading":false,"counters":{"__ALIAS_STORE__":true},"route":{"name":"","params":{},"query":{}}},"adblock":{"hasAcceptableAdsFilter":false,"hasAdblock":false},"pullRefresh":{"shouldRefresh":false},"viewport":{"prevScrollY":{},"scrollY":0,"width":0,"pageContentHeight":0},"feedStatistics":{"feedsStatistics":{}},"pageArticleComments":{"lastViewedComment":0,"postId":null,"lastCommentTimestamp":1618595904,"moderated":[],"moderatedIds":[],"commentRoute":"","idempotenceKey":""},"comments":{"articleComments":{"552462":{"refs":{"22926204":{"id":"22926204","parentId":null,"level":0,"timePublished":"2021-04-15T11:43:01+00:00","timeChanged":null,"isSuspended":false,"status":"published","score":2,"votesCount":2,"message":"«Помимо Billing Dashboard, соседний Cost Explorer.»\u003Cbr\u003E\r\nПрекрасный перевод…","editorVersion":1,"author":{"id":"79852","alias":"onyxmaster","fullname":"Аристарх Загородников","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002Fd43\u002F009\u002F6ed\u002Fd430096ed28b913cf7b65df42ea58326.jpg","speciality":"Jack of all trades, master of none"},"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":["22926234"],"vote":null,"votePlus":null,"voteMinus":null,"isPinned":false},"22926234":{"id":"22926234","parentId":"22926204","level":1,"timePublished":"2021-04-15T11:47:47+00:00","timeChanged":"2021-04-15T11:50:38+00:00","isSuspended":false,"status":"published","score":0,"votesCount":2,"message":"Спасибо за замечание. Исправил опечатку.","editorVersion":1,"author":{"id":"852506","alias":"mikhail_cloud","fullname":"Михаил Соколов","avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002Faa1\u002Fab3\u002F5cf\u002Faa1ab35cfa50b0c3309fb6eb6de70a59.jpg","speciality":"Архитектор Облачных Систем"},"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":[],"vote":null,"votePlus":null,"voteMinus":null,"isPinned":false},"22926426":{"id":"22926426","parentId":null,"level":0,"timePublished":"2021-04-15T12:37:48+00:00","timeChanged":null,"isSuspended":false,"status":"published","score":0,"votesCount":0,"message":"а портянку лямбды можно ка книть под кат спрятать?","editorVersion":1,"author":{"id":"384150","alias":"sergey_prokofiev","fullname":null,"avatarUrl":null,"speciality":null},"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":[],"vote":null,"votePlus":null,"voteMinus":null,"isPinned":false},"22926980":{"id":"22926980","parentId":null,"level":0,"timePublished":"2021-04-15T14:50:13+00:00","timeChanged":null,"isSuspended":false,"status":"published","score":0,"votesCount":0,"message":"\u003Cp\u003EВместо Lambda и генерации Excel файлов можно сделать Cost and Usage Report и потом \u003Ca href=\"https:\u002F\u002Fwellarchitectedlabs.com\u002Fcost\u002F300_labs\u002F300_cur_queries\u002Fquery_help\u002F\" rel=\"nofollow noopener noreferrer\"\u003Eделать запросы через Athena\u003C\u002Fa\u003E\u003C\u002Fp\u003E","editorVersion":1,"author":{"id":"205992","alias":"darken99","fullname":null,"avatarUrl":"\u002F\u002Fhabrastorage.org\u002Fgetpro\u002Fhabr\u002Favatars\u002F1b2\u002Fb06\u002F99a\u002F1b2b0699a5719b2cb1bd1d1ae190f342.jpg","speciality":"Cloud Solutions Architect"},"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":["22927614"],"vote":null,"votePlus":null,"voteMinus":null,"isPinned":false},"22927614":{"id":"22927614","parentId":"22926980","level":1,"timePublished":"2021-04-15T17:22:00+00:00","timeChanged":null,"isSuspended":false,"status":"published","score":1,"votesCount":1,"message":"+1 — мне тоже кажется что такие вещи можно сделать без кода","editorVersion":1,"author":{"id":"2054245","alias":"vitaly_il1","fullname":"Виталий","avatarUrl":null,"speciality":"DevOps"},"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":[],"vote":null,"votePlus":null,"voteMinus":null,"isPinned":false},"22929570":{"id":"22929570","parentId":null,"level":0,"timePublished":"2021-04-16T07:23:25+00:00","timeChanged":"2021-04-16T07:32:25+00:00","isSuspended":false,"status":"published","score":0,"votesCount":0,"message":"\u003Cblockquote\u003EПрежде чем начать работать, надо познакомиться со стандартным видом консоли Billing Dashboard. Нужно сначала включить её, что будет стоить денег. \u003C\u002Fblockquote\u003E\u003Cbr\u003E\r\n Хотите узнать куда уходят ваши денежки? Сначала заплатите!","editorVersion":1,"author":{"id":"779053","alias":"sergeyns","fullname":null,"avatarUrl":null,"speciality":null},"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":[],"vote":null,"votePlus":null,"voteMinus":null,"isPinned":false},"22930036":{"id":"22930036","parentId":null,"level":0,"timePublished":"2021-04-16T08:47:56+00:00","timeChanged":null,"isSuspended":false,"status":"published","score":0,"votesCount":0,"message":"\u003Cp\u003Eпро env.example тема не раскрыта\u003C\u002Fp\u003E","editorVersion":1,"author":{"id":"762577","alias":"SaTaI","fullname":null,"avatarUrl":null,"speciality":null},"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":[],"vote":null,"votePlus":null,"voteMinus":null,"isPinned":false},"22932420":{"id":"22932420","parentId":null,"level":0,"timePublished":"2021-04-16T17:58:24+00:00","timeChanged":null,"isSuspended":false,"status":"author_deactivated","score":0,"votesCount":0,"message":"UFO just landed and posted this here","editorVersion":0,"author":null,"isAuthor":false,"isPostAuthor":false,"isNew":false,"isFavorite":false,"isCanEdit":false,"timeEditAllowedTill":null,"children":[],"vote":{"value":null,"isCanVote":false},"votePlus":{"canVote":false,"isChargeEnough":false,"isKarmaEnough":false,"isVotingOver":false,"isPublicationLimitEnough":false},"voteMinus":{"canVote":false,"isChargeEnough":false,"isKarmaEnough":false,"isVotingOver":false,"isPublicationLimitEnough":false},"isPinned":false}},"root":["22926204","22926426","22926980","22929570","22930036","22932420"],"cacheKey":"d93fcc8b-5996-4dd5-a519-606e27c652fb"}},"articlePinnedComments":{"552462":{"refs":{},"commentIds":[]}},"searchCommentsResults":null,"pagesCount":null,"commentAccess":{},"scrollParents":{}},"publicationStats":{"statsInfo":{},"statsFunnels":{},"statsGraph":{},"defaultSuggest":{},"suggest":{},"timeTracker":{},"isUserActive":true,"otherPublicationStats":{}}};(function(){var s=document.currentScript||document.scripts[document.scripts.length-1];s.parentNode.removeChild(s);}());
Pull to refresh

Comments 8

«Помимо Billing Dashboard, соседний Cost Explorer.»
Прекрасный перевод…
+1 — мне тоже кажется что такие вещи можно сделать без кода
Прежде чем начать работать, надо познакомиться со стандартным видом консоли Billing Dashboard. Нужно сначала включить её, что будет стоить денег.

Хотите узнать куда уходят ваши денежки? Сначала заплатите!
UFO landed and left these words here
Sign up to leave a comment.

Articles