KubeVela: 如何用 100 行代码快速引入 AWS 最受欢迎的 50 种云资源

本文涉及的产品
云原生网关 MSE Higress,422元/月
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文提供了一个方案,用不到 100 行代码快速引入 AWS 前 50 最受欢迎的云资源。

作者:KubeVela 社区


KubeVela 目前已经支持了 AWS、Azure、GCP、阿里云、腾讯云、百度云、UCloud 等云厂商,也提供了简单快捷的命令行工具[1]引入云服务商的云资源,但是在 KubeVela 里一个一个地支持云服务商的云资源不利于快速满足用户对于云资源的需求,本文提供了一个方案,用不到 100 行代码快速引入 AWS 前 50 最受欢迎的云资源。

同时,我们也期望用户受到本文的启发,贡献其他云服务商的云资源。


AWS 最受欢迎的云资源在哪里?


Terraform 官网提供了各个云服务商的 Terraform modules,比如 AWS 的云资源 Terraform modules[2]。其中,云资源按照受欢迎的使用程度(下载量)排序,比如 AWS VPC 下载量为 1870 万次。


通过简单分析,我们发现 AWS 前 50 Terraform modules 的数据可以通过请求 https://registry.terraform.io/v2/modules?filter%5Bprovider%5D=aws&include=latest-version&page%5Bsize%5D=50&page%5Bnumber%5D=1 获取。


开始之前


代码接受两个用户传入参数:

  • provider 的名称
  • 该 provider 对应的 Terraform Modules 的 URL


对于 AWS 来说,Provider名称为 “aws”,对应的 Terraform modules 为 Terraform Modules json 格式接口[3](即在 Terraform Registry[4]中搜索 provider 为 aws 时最受欢迎的 50 种云资源)。

在执行代码之前需要确认 providerName(aws) 和 Modules 链接无误。


执行代码


那么你就可以通过以下 100 行左右的代码(文件名 gen.go)来批量地快速引入 AWS 最受欢迎的前 50 种云资源。


import (
  "encoding/json"
  "fmt"
  "io"
  "log"
  "net/http"
  "os"
  "os/exec"
  "path/filepath"
  "strings"
  "github.com/pkg/errors"
)
type TFDownload struct {
  Data     []DataItem     `json:"data"`
  Included []IncludedItem `json:"included"`
}
type IncludedItem struct {
  Id         string     `json:"id"`
  Attributes Attributes `json:"attributes"`
}
type DataItem struct {
  Attributes    Attributes    `json:"attributes"`
  Relationships Relationships `json:"relationships"`
}
type Relationships struct {
  LatestVersion RelationshipLatestVersion `json:"latest-version"`
}
type RelationshipLatestVersion struct {
  Data RelationshipData `json:"data"`
}
type RelationshipData struct {
  Id string `json:"id"`
}
var errNoVariables = errors.New("failed to find main.tf or variables.tf in Terraform configurations")
type Attributes struct {
  Name        string `json:"name"`
  Downloads   int    `json:"downloads"`
  Source      string `json:"source"`
  Description string `json:"description"`
  Verified    bool   `json:"verified"`
}
func main() {
  if len(os.Args) < 2 {
     fmt.Println("Please provide the cloud provider name and an official Terraform modules URL")
     os.Exit(1)
  }
  providerName := os.Args[1]
  terraformModulesUrl := os.Args[2]
  resp, err := http.Get(terraformModulesUrl)
  if err != nil {
     log.Fatal(err)
  }
  defer resp.Body.Close()
  body, err := io.ReadAll(resp.Body)
  if err != nil {
     log.Fatal(err)
  }
  var modules TFDownload
  if err := json.Unmarshal(body, &modules); err != nil {
     fmt.Println(err.Error())
     os.Exit(1)
  }
  if _, err = os.Stat(providerName); err == nil {
     if err := os.RemoveAll(providerName); err != nil {
        log.Fatal(err)
     }
     fmt.Printf("Successfully deleted existed directory %s\n", providerName)
  }
  if _, err = os.Stat(providerName); os.IsNotExist(err) {
     if err := os.Mkdir(providerName, 0755); err != nil {
        if !os.IsExist(err) {
           log.Fatal(err)
        }
        fmt.Printf("Successfully created directory %s\n", providerName)
     }
  }
  for _, module := range modules.Data {
     var description string
     for _, attr := range modules.Included {
        if module.Relationships.LatestVersion.Data.Id == attr.Id {
           description = attr.Attributes.Description
        }
     }
     if description == "" {
        description = strings.ToUpper(providerName) + " " + strings.Title(module.Attributes.Name)
     }
     outputFile := fmt.Sprintf("%s/terraform-%s-%s.yaml", providerName, providerName, module.Attributes.Name)
     if _, err := os.Stat(outputFile); !os.IsNotExist(err) {
        continue
     }
     if providerName == "aws" && (module.Attributes.Name == "rds" || module.Attributes.Name == "s3-bucket" ||
        module.Attributes.Name == "subnet" || module.Attributes.Name == "vpc") {
        continue
     }
     if err := generateDefinition(providerName, module.Attributes.Name, module.Attributes.Source, "", description); err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
     }
  }
}
func generateDefinition(provider, name, gitURL, path, description string) error {
  defYaml := filepath.Join(provider, fmt.Sprintf("terraform-%s-%s.yaml", provider, name))
  cmd := fmt.Sprintf("vela def init %s --type component --provider %s --git %s.git --desc \"%s\" -o %s",
     name, provider, gitURL, description, defYaml)
  if path != "" {
     cmd = fmt.Sprintf("%s --path %s", cmd, path)
  }
  fmt.Println(cmd)
  stdout, err := exec.Command("bash", "-c", cmd).CombinedOutput()
  if err != nil {
     return errors.Wrap(err, string(stdout))
  }
  fmt.Println(string(stdout))
  return nil


执行命令:


go run gen.go aws "https://registry.terraform.io/v2/modules?filter%5Bprovider%5D=aws&include=latest-version&page%5Bsize%5D=50&page%5Bnumber%5D=1"



代码简要说明

解析云资源数据


访问用户传入的 URL,将返回的 json 数据解析为 Go 中的结构体。

资源对应的 json 格式如下:


{
  "data": [
    {
      "type": "modules",
      "id": "23",
      "attributes": {
        "downloads": 18440513,
        "full-name": "terraform-aws-modules/vpc/aws",
        "name": "vpc",
        "namespace": "terraform-aws-modules",
        "owner-name": "",
        "provider-logo-url": "/images/providers/aws.png",
        "provider-name": "aws",
        "source": "https://github.com/terraform-aws-modules/terraform-aws-vpc",
        "verified": true
      },
      "relationships": {
        "latest-version": {
          "data": {
            "id": "142143",
            "type": "module-versions"
          }
        }
      },
      "links": {
        "self": "/v2/modules/23"
      }
    },
    ...
  ],
  "included": [
    {
      "type": "module-versions",
      "id": "36806",
      "attributes": {
        "created-at": "2020-01-03T11:35:36Z",
        "description": "Terraform module Terraform module for creating AWS IAM Roles with heredocs",
        "downloads": 260030,
        "published-at": "2020-02-06T06:26:08Z",
        "source": "",
        "tag": "v2.0.0",
        "updated-at": "2022-02-22T00:45:44Z",
        "version": "2.0.0"
      },
      "links": {
        "self": "/v2/module-versions/36806"
      }
    },
    ...
  ],
  ...
}


在 Modules 对应的 json 数据中,我们只关心两个键值对,即:


  • data:包含 Modules 名称及属性的列表
  • Included:筛选出的特定版本的 Modules 具体信息


其中,对于 data 中的每个 Module 元素,解析它的属性,Id 和 relationship 中的 latest-version 对应的 id;对于 Included 中的每个 Module 版本元素,解析它的属性和Id。


属性又解析如下五项:

  • Name
  • Downloads
  • Source
  • Description
  • Verified


结构体定义在结构体 TFDownload 中,通过 http 库获取 json 数据,再通过 json.Unmarshal 解析出 Terraform modules 的结构体。


批量生产云资源


  1. 新建目录,生成资源所需文件


解析完毕后,在当前目录下新建文件夹,文件夹命名为 provider 名称。

遍历解析后的 data,对于其中每个 Module 元素,执行下述操作,为其生成相应配置文件,定义和相应文档。


  1. 生成定义文件


通过下述 vela 指令从模块对应的 github 仓库读取相应信息生成定义文件。


vela def init {ModuleName} --type component --provider {providerName} --git {gitURL} --desc {description} -o {yamlFileName}


指令中需要填入的几项由解析好的 Module 结构体传入。


  • gitURL: {Module.Attributes.Source}.git
  • description: 如果 Included 中存在元素 ID 与模块 relationship 中 latest-version 对应 ID 相同,则 description 为 Included 中对应元素属性的 description;否则 description 为 providerName 与模块名称的拼接
  • yamlFileName:terraform-{providerName}-{Module.Attributes.Name}.yaml


你也来试试?


还有不少云服务商也提供了丰富的 Terraform modules,比如


GCP:

https://registry.terraform.io/namespaces/terraform-google-modules


阿里云:

https://registry.terraform.io/namespaces/terraform-alicloud-modules


你要不要也为 KubeVela 引入你正在使用的、或喜欢的云服务商的云资源?


相关链接


[1] 简单快捷的命令行工具

https://kubevela.io/docs/next/platform-engineers/components/component-terraform


[2] AWS 的云资源 Terraform modules

https://registry.terraform.io/namespaces/terraform-aws-modules


[3] Terraform Modules json 格式接口

https://registry.terraform.io/v2/modules?filter%5Bprovider%5D=aws&include=latest-version&page%5Bsize%5D=50&page%5Bnumber%5D=1


[4] Terraform Registry

https://aregistry.terraform.io/

相关实践学习
基于Hologres轻量实时的高性能OLAP分析
本教程基于GitHub Archive公开数据集,通过DataWorks将GitHub中的项⽬、行为等20多种事件类型数据实时采集至Hologres进行分析,同时使用DataV内置模板,快速搭建实时可视化数据大屏,从开发者、项⽬、编程语⾔等多个维度了解GitHub实时数据变化情况。
相关文章
|
12月前
|
数据采集 机器学习/深度学习 自然语言处理
数据清洗与过滤
【10月更文挑战第6天】数据清洗与过滤
197 1
|
弹性计算 Cloud Native Devops
云效DevStudio体验
阿里云中提供了在线编辑工具DevStudio,让开发更加便捷。
2325 0
云效DevStudio体验
|
10月前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
837 55
|
11月前
|
缓存 前端开发 JavaScript
前端开发的必修课:如何让你的网页在弱网环境下依然流畅运行?
【10月更文挑战第30天】随着移动互联网的普及,弱网环境下的网页性能优化变得尤为重要。本文详细介绍了如何通过了解网络状况、优化资源加载、减少HTTP请求、调整弱网参数和代码优化等方法,提升网页在弱网环境下的加载速度和流畅性,从而改善用户体验。
593 4
|
11月前
|
机器学习/深度学习 数据可视化 数据挖掘
数据集中存在大量重复值时,如何选择合适的分析方法?
总之,当数据集中存在大量重复值时,需要综合考虑各种分析方法的特点和适用范围,根据具体的分析目标和数据情况选择合适的方法,或者结合多种方法进行综合分析,以获得准确、可靠的分析结果。
414 65
|
9月前
|
机器学习/深度学习 弹性计算 人工智能
阿里云服务器ECS架构区别及选择参考:X86计算、ARM计算等架构介绍
在我们选购阿里云服务器的时候,云服务器架构有X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、高性能计算可选,有的用户并不清楚他们之间有何区别,本文主要简单介绍下这些架构各自的主要性能及适用场景,以便大家了解不同类型的架构有何不同,主要特点及适用场景有哪些。
1257 10
|
11月前
|
Python
044[词根溯源]declaration_变量含义_meaning_声明
本文回顾了上期制作ASCII码表的内容,并深入探讨了变量的概念及其在不同场景下的应用,如火车票预订、教务系统及游戏开发中变量的变化与使用。文章还介绍了Python中变量的声明与赋值方法,以及“声明”一词的词源解析,强调了声明变量的重要性,为后续学习如何使用变量做了铺垫。
184 6
|
11月前
Lua
【11月更文挑战第20天】
263 3
|
算法 数据挖掘 API
贝叶斯统计在Python数据分析中的高级技术点:贝叶斯推断、概率编程和马尔科夫链蒙特卡洛
贝叶斯统计在Python数据分析中的高级技术点:贝叶斯推断、概率编程和马尔科夫链蒙特卡洛
252 1
贝叶斯统计在Python数据分析中的高级技术点:贝叶斯推断、概率编程和马尔科夫链蒙特卡洛
|
12月前
|
关系型数据库 MySQL BI
帆软Report 填报
帆软Report 填报
442 0