본문 바로가기
Cloud

Go언어로 AWS Price List API(Bulk API) 사용하는 예제

by weero 2023. 2. 24.

 

 

AWS는 가격을 쿼리할 때 Bulk API와 Query API를 제공하고 있는데,

  • AWS Price List Bulk API : AWS 서비스의 가격을 대량으로 쿼리해 JSON 또는 CSV 파일로 반환한다.
  • AWS Price List Query API : AWS SDK 또는 AWS CLI를 통해 AWS 서비스, 제품, 요금에 대한 특정 정보를 쿼리할 수 있다. (특정 제품 또는 가격에 대한 정보)

 

AWS의 모든 리전에서 서비스별 가격 정보가 담긴 CSV 파일을 다운로드 받는 것이 목적이기 때문에 Bulk API를 사용해보기로 했다.

 

사용 방법은 단순하다. 요금 내역을 다운로드 할 수 있는 url를 웹 브라우저에 실행하기만 해도 AWS 서비스에 대한 가격정보가 담긴 제안파일을 다운로드할 수 있다.

  • 제안 인덱스 파일(offer index file) : bulk api가 지원되는 AWS 서비스와 이에 대한 요금 내역을 다운로드할 수 있는 제안파일의 url이 명시된 JSON 파일이다.
    • 제안 인덱스 파일에 대한 메타 데이터
    • 서비스 제안 파일에 대한 URL
    • 리전별 제안 인덱스 파일에 대한 URL
  • 제안 파일 (offer file) : 모든 리전 또는 특정 리전의 단일 AWS 서비스에 대한 제품 및 가격 목록이 들어있는 JSON 또는 CSV 파일이다.

 

따라서,

  1. 제안 인덱스 파일에서 지원되는 AWS 서비스의 목록을 가져와서,
  2. 해당 서비스에 대한 요금 정보가 나와있는 제안파일 uri를 통해 CSV 파일을 다운로드한다.

 

위 내용을 옮긴게 아래 코드이다.

 

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
)

type offerIndex struct {
	FormatVersion   string           `json:"formatVersion"`
	Disclaimer      string           `json:"disclaimer"`
	PublicationDate string           `json:"publicationDate"`
	Offers          map[string]offer `json:"offers"`
}

type offer struct {
	OfferCode             string `json:"offerCode"`
	VersionIndexUrl       string `json:"versionIndexUrl"`
	CurrentVersionUrl     string `json:"currentVersionUrl"`
	CurrentRegionIndexUrl string `json:"currentRegionIndexUrl"`
}

func main() {
	// 제안 인덱스 파일 다운로드
	fileUrl := "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/index.json"
	err := DownloadFile("index.json", fileUrl)
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}
	fmt.Println("downloaded: " + fileUrl)

	// 제안 인덱스 파일 읽기
	indexFile, err := ioutil.ReadFile("./index.json")
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	var data offerIndex
	err = json.Unmarshal(indexFile, &data)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	// 제안 파일 다운로드
	for key, value := range data.Offers {
		serviceFileUrl := fmt.Sprintf("https://pricing.us-east-1.amazonaws.com%s.csv", value.CurrentVersionUrl[:len(value.CurrentVersionUrl)-5])
		err = DownloadFile(fmt.Sprintf("%s.csv", key), serviceFileUrl)
		if err != nil {
			fmt.Println(err.Error())
			panic(err)
		}
		fmt.Println("downloaded: " + fileUrl)
	}

}

func DownloadFile(filePath string, url string) error {
	resp, err := http.Get(url)
	if err != nil {
		fmt.Println(err.Error())
		return err
	}
	defer resp.Body.Close()

	out, err := os.Create(filePath)
	if err != nil {
		fmt.Println(err.Error())
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, resp.Body)
	return err
}

 

아래처럼 잘 파일이 뽑혀있는 것을 확인할 수 있다.

 

 

 

출처: https://docs.aws.amazon.com/ko_kr/awsaccountbilling/latest/aboutv2/price-changes.html