Example #1
0
        /// <summary>
        /// コスト超過しているか確認する
        /// </summary>
        /// <param name="awsAccessKey">AWSアクセスキー</param>
        /// <param name="awsSecretKey">AWSシークレットキー</param>
        /// <param name="limit">超過とみなす閾値</param>
        private static string getLimitoverCost(string awsAccessKey, string awsSecretKey, decimal limit)
        {
            AmazonCostExplorerClient client = new AmazonCostExplorerClient(awsAccessKey, awsSecretKey, RegionEndpoint.USEast1);
            GetCostAndUsageRequest   req    = new GetCostAndUsageRequest();

            req.TimePeriod       = new DateInterval();
            req.TimePeriod.Start = DateTime.Now.AddDays(-3).ToString("yyyy-MM-dd"); // 3日前~本日までチェック
            req.TimePeriod.End   = DateTime.Now.ToString("yyyy-MM-dd");
            req.Granularity      = Granularity.DAILY;
            req.Metrics          = new List <string>()
            {
                "AMORTIZED_COST"
            };

            StringBuilder           sb   = new StringBuilder(); // 超過情報
            GetCostAndUsageResponse cost = client.GetCostAndUsage(req);

            for (int i = 0; i < cost.ResultsByTime.Count; i++)
            {
                string start = cost.ResultsByTime[i].TimePeriod.Start;
                string end   = cost.ResultsByTime[i].TimePeriod.End;
                foreach (string key in cost.ResultsByTime[i].Total.Keys)
                {
                    decimal amount = decimal.Parse(cost.ResultsByTime[i].Total[key].Amount);
                    string  unit   = cost.ResultsByTime[i].Total[key].Unit;
                    if (amount > limit)  // 閾値を超えた
                    {
                        sb.Append(start + "~" + end + " Amount=" + amount + " Unit=" + unit + Environment.NewLine);
                    }
                }
            }
            return(sb.ToString());
        }
Example #2
0
        /// <summary>
        /// Retrieves cost and usage metrics for your account. You can specify which cost and
        /// usage-related metric, such as <code>BlendedCosts</code> or <code>UsageQuantity</code>,
        /// that you want the request to return. You can also filter and group your data by various
        /// dimensions, such as <code>SERVICE</code> or <code>AZ</code>, in a specific time range.
        /// For a complete list of valid dimensions, see the <a href="http://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_GetDimensionValues.html">GetDimensionValues</a>
        /// operation. Master accounts in an organization in AWS Organizations have access to
        /// all member accounts.
        /// </summary>
        /// <param name="request">Container for the necessary parameters to execute the GetCostAndUsage service method.</param>
        ///
        /// <returns>The response from the GetCostAndUsage service method, as returned by CostExplorer.</returns>
        /// <exception cref="Amazon.CostExplorer.Model.BillExpirationException">
        /// The requested report expired. Update the date interval and try again.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.DataUnavailableException">
        /// The requested data is unavailable.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.InvalidNextTokenException">
        /// The pagination token is invalid. Try again without a pagination token.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.LimitExceededException">
        /// You made too many calls in a short period of time. Try again later.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.RequestChangedException">
        /// Your request parameters changed between pages. Try again with the old parameters or
        /// without a pagination token.
        /// </exception>
        /// <seealso href="http://docs.aws.amazon.com/goto/WebAPI/ce-2017-10-25/GetCostAndUsage">REST API Reference for GetCostAndUsage Operation</seealso>
        public virtual GetCostAndUsageResponse GetCostAndUsage(GetCostAndUsageRequest request)
        {
            var marshaller   = GetCostAndUsageRequestMarshaller.Instance;
            var unmarshaller = GetCostAndUsageResponseUnmarshaller.Instance;

            return(Invoke <GetCostAndUsageRequest, GetCostAndUsageResponse>(request, marshaller, unmarshaller));
        }
Example #3
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("application started..");
            try
            {
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                log.LogInformation("requestBody : " + requestBody);
                GetCostAndUsageRequest costAndUsageRequest = JsonConvert.DeserializeObject <GetCostAndUsageRequest>(requestBody);
                //GetCostAndUsageRequest costAndUsageRequest = BuildAWSCostAndUsageRequest(data);
                log.LogInformation("Build JSON Completed and AWS call initiated..");
                GetCostAndUsageResponse costAndUsageResponse = CallAWSCostAndUsageAPI(costAndUsageRequest);
                log.LogInformation("AWS call Completed..");

                CanonicalResponse canonicalresponse = CreateCanonicalData(costAndUsageResponse);

                log.LogInformation("Canonical response completed..");
                // Insert JSON Response into Cosmos DB
                ProcessCosmosDB cosmosDB = new ProcessCosmosDB();
                log.LogInformation("DB initiated..");
                await cosmosDB.GetStartedDemoAsync(canonicalresponse);

                log.LogInformation("processed response completed..");
                return(new OkObjectResult(costAndUsageResponse));
            }
            catch (Exception ex)
            {
                log.LogInformation("Error occured in AWS Cost and Usage " + ex.Message.ToString());
                return(new BadRequestObjectResult(ex.Message.ToString()));
            }
        }
Example #4
0
        /// <summary>
        /// Initiates the asynchronous execution of the GetCostAndUsage operation.
        /// </summary>
        ///
        /// <param name="request">Container for the necessary parameters to execute the GetCostAndUsage operation.</param>
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        /// <seealso href="http://docs.aws.amazon.com/goto/WebAPI/ce-2017-10-25/GetCostAndUsage">REST API Reference for GetCostAndUsage Operation</seealso>
        public virtual Task <GetCostAndUsageResponse> GetCostAndUsageAsync(GetCostAndUsageRequest request, System.Threading.CancellationToken cancellationToken = default(CancellationToken))
        {
            var marshaller   = GetCostAndUsageRequestMarshaller.Instance;
            var unmarshaller = GetCostAndUsageResponseUnmarshaller.Instance;

            return(InvokeAsync <GetCostAndUsageRequest, GetCostAndUsageResponse>(request, marshaller,
                                                                                 unmarshaller, cancellationToken));
        }
Example #5
0
        /// <summary>
        /// Initiates the asynchronous execution of the GetCostAndUsage operation.
        /// </summary>
        ///
        /// <param name="request">Container for the necessary parameters to execute the GetCostAndUsage operation on AmazonCostExplorerClient.</param>
        /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param>
        /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback
        ///          procedure using the AsyncState property.</param>
        ///
        /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndGetCostAndUsage
        ///         operation.</returns>
        /// <seealso href="http://docs.aws.amazon.com/goto/WebAPI/ce-2017-10-25/GetCostAndUsage">REST API Reference for GetCostAndUsage Operation</seealso>
        public virtual IAsyncResult BeginGetCostAndUsage(GetCostAndUsageRequest request, AsyncCallback callback, object state)
        {
            var marshaller   = new GetCostAndUsageRequestMarshaller();
            var unmarshaller = GetCostAndUsageResponseUnmarshaller.Instance;

            return(BeginInvoke <GetCostAndUsageRequest>(request, marshaller, unmarshaller,
                                                        callback, state));
        }
        /// <summary>
        /// Retrieves cost and usage metrics for your account. You can specify which cost and
        /// usage-related metric, such as <code>BlendedCosts</code> or <code>UsageQuantity</code>,
        /// that you want the request to return. You can also filter and group your data by various
        /// dimensions, such as <code>SERVICE</code> or <code>AZ</code>, in a specific time range.
        /// For a complete list of valid dimensions, see the <a href="http://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_GetDimensionValues.html">GetDimensionValues</a>
        /// operation. Master accounts in an organization in AWS Organizations have access to
        /// all member accounts.
        /// </summary>
        /// <param name="request">Container for the necessary parameters to execute the GetCostAndUsage service method.</param>
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
        ///
        /// <returns>The response from the GetCostAndUsage service method, as returned by CostExplorer.</returns>
        /// <exception cref="Amazon.CostExplorer.Model.BillExpirationException">
        /// The requested report expired. Update the date interval and try again.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.DataUnavailableException">
        /// The requested data is unavailable.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.InvalidNextTokenException">
        /// The pagination token is invalid. Try again without a pagination token.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.LimitExceededException">
        /// You made too many calls in a short period of time. Try again later.
        /// </exception>
        /// <exception cref="Amazon.CostExplorer.Model.RequestChangedException">
        /// Your request parameters changed between pages. Try again with the old parameters or
        /// without a pagination token.
        /// </exception>
        /// <seealso href="http://docs.aws.amazon.com/goto/WebAPI/ce-2017-10-25/GetCostAndUsage">REST API Reference for GetCostAndUsage Operation</seealso>
        public virtual Task <GetCostAndUsageResponse> GetCostAndUsageAsync(GetCostAndUsageRequest request, System.Threading.CancellationToken cancellationToken = default(CancellationToken))
        {
            var options = new InvokeOptions();

            options.RequestMarshaller    = GetCostAndUsageRequestMarshaller.Instance;
            options.ResponseUnmarshaller = GetCostAndUsageResponseUnmarshaller.Instance;

            return(InvokeAsync <GetCostAndUsageResponse>(request, options, cancellationToken));
        }
        internal virtual GetCostAndUsageResponse GetCostAndUsage(GetCostAndUsageRequest request)
        {
            var options = new InvokeOptions();

            options.RequestMarshaller    = GetCostAndUsageRequestMarshaller.Instance;
            options.ResponseUnmarshaller = GetCostAndUsageResponseUnmarshaller.Instance;

            return(Invoke <GetCostAndUsageResponse>(request, options));
        }
Example #8
0
        /// <summary>
        /// Initiates the asynchronous execution of the GetCostAndUsage operation.
        /// </summary>
        ///
        /// <param name="request">Container for the necessary parameters to execute the GetCostAndUsage operation on AmazonCostExplorerClient.</param>
        /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param>
        /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback
        ///          procedure using the AsyncState property.</param>
        ///
        /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndGetCostAndUsage
        ///         operation.</returns>
        /// <seealso href="http://docs.aws.amazon.com/goto/WebAPI/ce-2017-10-25/GetCostAndUsage">REST API Reference for GetCostAndUsage Operation</seealso>
        public virtual IAsyncResult BeginGetCostAndUsage(GetCostAndUsageRequest request, AsyncCallback callback, object state)
        {
            var options = new InvokeOptions();

            options.RequestMarshaller    = GetCostAndUsageRequestMarshaller.Instance;
            options.ResponseUnmarshaller = GetCostAndUsageResponseUnmarshaller.Instance;

            return(BeginInvoke(request, options, callback, state));
        }
Example #9
0
        public async Task <GetCostAndUsageResponse> GetCostAndUsage(GetCostAndUsageRequest costUsageRequest)
        {
            using (var amazonCostExplorerClient = new AmazonCostExplorerClient(awsCredentials, RegionEndpoint.GetBySystemName("us-east-1")))
            {
                var response = await amazonCostExplorerClient.GetCostAndUsageAsync(costUsageRequest);

                return(response);
            }
        }
Example #10
0
        //private static GetCostAndUsageRequest BuildAWSCostAndUsageRequest(object data)
        //{

        //    GetCostAndUsageRequest costAndUsageRequest = new GetCostAndUsageRequest();
        //    //string jsonString = File.ReadAllText(@"costandusageresquest.json");
        //    costAndUsageRequest = JsonConvert.DeserializeObject<GetCostAndUsageRequest>(data.ToString());
        //    return costAndUsageRequest;
        //}
        private static GetCostAndUsageResponse CallAWSCostAndUsageAPI(GetCostAndUsageRequest costAndUsageRequest)
        {
            var client = new AmazonCostExplorerClient(
                awsAccessKeyId: Environment.GetEnvironmentVariable("awsAccessKeyId"),
                awsSecretAccessKey: Environment.GetEnvironmentVariable("awsSecretAccessKey"),
                Amazon.RegionEndpoint.USEast1);

            GetCostAndUsageResponse costAndUsageResponse = client.GetCostAndUsageAsync(costAndUsageRequest).Result;

            return(costAndUsageResponse);
        }
        public async ValueTask <GetCostAndUsageResponse> GetByDate(DateTime start, DateTime end)
        {
            var client  = new AmazonCostExplorerClient();
            var request = new GetCostAndUsageRequest
            {
                TimePeriod = new DateInterval()
                {
                    Start = $"{start:yyyy-MM-dd}",
                    End   = $"{end:yyyy-MM-dd}"
                },
                Granularity = Granularity.DAILY
            };

            request.Metrics.Add("BlendedCost");
            request.GroupBy = new List <GroupDefinition>()
            {
                new GroupDefinition()
                {
                    Key = "SERVICE", Type = GroupDefinitionType.DIMENSION
                }
            };
            return(await client.GetCostAndUsageAsync(request));
        }
Example #12
0
        public static void GetCostsAndUsage()
        {
            Console.WriteLine(Utils.CurrentMethod);
            GetCostAndUsageRequest request = new GetCostAndUsageRequest();

            request.TimePeriod = new DateInterval()
            {
                Start = "2019-04-01", End = "2019-05-01"
            };
            request.Granularity = Granularity.MONTHLY;
            request.Metrics     = new List <string>();
            request.Metrics.Add(Metric.AMORTIZED_COST);
            request.Metrics.Add(Metric.BLENDED_COST);
            request.Metrics.Add(Metric.NET_AMORTIZED_COST);
            request.Metrics.Add(Metric.NET_UNBLENDED_COST);
            request.Metrics.Add(Metric.NORMALIZED_USAGE_AMOUNT);
            request.Metrics.Add(Metric.UNBLENDED_COST);
            request.Metrics.Add(Metric.USAGE_QUANTITY);

            request.GroupBy = new List <GroupDefinition>();
            request.GroupBy.Add(new GroupDefinition {
                Type = GroupDefinitionType.DIMENSION, Key = Dimension.LINKED_ACCOUNT
            });
            request.GroupBy.Add(new GroupDefinition {
                Type = GroupDefinitionType.TAG, Key = "cloud-environment"
            });
//            request.GroupBy.Add(new GroupDefinition { Type = GroupDefinitionType.DIMENSION, Key = Dimension.SERVICE });

            bool keepLooking = true;
            int  callCount   = 0;

            while (keepLooking)
            {
                Task <GetCostAndUsageResponse> t = client.GetCostAndUsageAsync(request);
                t.Wait(30000);
                GetCostAndUsageResponse response = t.Result;

                string json = JsonTools.Serialize(response, true);
                Console.WriteLine(json);

                String fileName = $"/Users/guy/temp/cost-and-usage-{callCount.ToString().PadLeft(4, '0')}.json";
                File.WriteAllText(fileName, json);

                string nextPageToken = response.NextPageToken;

                if (String.IsNullOrWhiteSpace(nextPageToken))
                {
                    keepLooking = false;
                }
                else if (callCount > 100)
                {
                    keepLooking = false;
                }
                else
                {
                    request.NextPageToken = nextPageToken;
                }

                callCount++;
            }
        }
        public async override Task <IEnumerable <CostDto> > Handle(GetMonthlyTotalCostCommand command, CancellationToken cancellationToken = default)
        {
            var result = new List <CostDto>();

            using var client = _awsClientFactory.Create <AmazonCostExplorerClient>(command.AssumeProfile);

            try
            {
                GetCostAndUsageResponse resp = null;

                do
                {
                    var request = new GetCostAndUsageRequest()
                    {
                        Metrics       = new List <string>(new[] { Amazon.CostExplorer.Metric.BLENDED_COST.Value }),
                        TimePeriod    = CreateDateIntervalForCurrentMonth(),
                        Granularity   = Granularity.MONTHLY,
                        NextPageToken = resp?.NextPageToken
                    };

                    if (!string.IsNullOrEmpty(command.AccountIdentifier))
                    {
                        request.Filter = new Expression
                        {
                            Dimensions = new DimensionValues()
                            {
                                Key    = Dimension.LINKED_ACCOUNT,
                                Values = new List <string>()
                                {
                                    command.AccountIdentifier
                                }
                            }
                        };
                    }
                    else
                    {
                        request.GroupBy = new List <GroupDefinition>(new[]
                        {
                            new GroupDefinition()
                            {
                                Type = GroupDefinitionType.DIMENSION,
                                Key  = Dimension.LINKED_ACCOUNT.Value
                            }
                        });
                    }

                    resp = await client.GetCostAndUsageAsync(request, cancellationToken);

                    var dto = new CostDto
                    {
                        DimensionValueAttributes = resp.DimensionValueAttributes?.Select(o => new DimensionValueAttributeDto
                        {
                            Attributes = o.Attributes,
                            Value      = o.Value
                        }),

                        ResultsByTime = resp.ResultsByTime?.Select(o => new ResultByTimeDto
                        {
                            Total = o.Total?.Select(kvp => new KeyValuePair <string, MetricValueDto>(kvp.Key, new MetricValueDto
                            {
                                Amount = kvp.Value.Amount,
                                Unit   = kvp.Value.Unit
                            })),
                            StartDate = DateTime.Parse(o.TimePeriod.Start),
                            EndDate   = DateTime.Parse(o.TimePeriod.End),
                            Estimated = o.Estimated,
                            Groups    = o.Groups?.Select(g => new GroupDto
                            {
                                Keys    = g.Keys?.AsEnumerable(),
                                Metrics = g.Metrics?.Select(m => new KeyValuePair <string, MetricValueDto>(m.Key, new MetricValueDto
                                {
                                    Amount = m.Value.Amount,
                                    Unit   = m.Value.Unit
                                }))
                            })
                        })
                    };

                    result.Add(dto);
                }while (resp.NextPageToken != null);
            }
            catch (AmazonServiceException e)
            {
                throw new Exception(e.Message, e);
            }

            return(result.AsEnumerable());
        }
Example #14
0
        public async Task <bool> FunctionHandler(ILambdaContext context)
        {
            // AWS側の集計に時間を要するため、2日前の利用量を集計する
            var start = DateTime.Now.AddDays(-2).ToString("yyyy-MM-dd");
            var end   = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");

            var ceRequest = new GetCostAndUsageRequest
            {
                TimePeriod = new DateInterval()
                {
                    Start = start,
                    End   = end
                },
                Granularity = "DAILY",
                Metrics     = new List <string>()
                {
                    METRICS
                },
                GroupBy = new List <GroupDefinition>()
                {
                    new GroupDefinition
                    {
                        Type = "DIMENSION",
                        Key  = "SERVICE"
                    }
                }
            };

            using var ceClient = new AmazonCostExplorerClient(region);
            var ceResponse = await ceClient.GetCostAndUsageAsync(ceRequest);

            decimal total  = 0;
            var     fields = new List <Field>();

            foreach (var result in ceResponse.ResultsByTime)
            {
                foreach (var group in result.Groups)
                {
                    var cost = Math.Round(Convert.ToDecimal(group.Metrics[METRICS].Amount) * RATE, 0);

                    fields.Add(new Field()
                    {
                        title  = group.Keys[0],
                        value  = String.Format(":moneybag: {0:#,0} 円", cost),
                        @short = true
                    });

                    total += cost;
                }
            }

            var color      = total == 0 ? "good" : "danger";
            var attachment = new Attachment()
            {
                fallback = "Required plain-text summery of the attachment.",
                color    = color,
                pretext  = String.Format("*{0} のAWS利用料は {1:#,0}円 です*", start, total),
                fields   = fields,
                channel  = SLACK_CHANNEL,
                username = "******"
            };

            var jsonSting = JsonConvert.SerializeObject(attachment);
            var content   = new FormUrlEncodedContent(new Dictionary <string, string>
            {
                { "payload", jsonSting }
            });

            var webhookUrl = await GetWebhookUrl();

            try
            {
                using var httpClient = new HttpClient();
                await httpClient.PostAsync(webhookUrl, content);
            }
            catch (Exception e)
            {
                context.Logger.LogLine("Exception: " + e.Message);
            }

            return(true);
        }