KubeVela: 如何用 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 元素,执行下述操作,为其生成相应配置文件,定义和相应文档。
2. 生成定义文件
通过下述 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 格式接口
[4] Terraform Registry

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
想让DBA瞬间崩溃,那就让他去做SQL性能优化
摘要:很多大数据计算都是用 SQL 实现的,跑得慢时就要去优化 SQL,但常常碰到让人干瞪眼的情况。 本文分享自华为云社区《做 SQL 性能优化真是让人干瞪眼》,作者: 石臻臻的杂货铺 。 很多大数据计算都是用 SQL 实现的,跑得慢时就要去优化 SQL,但常常碰到让人干瞪眼的情况。比如,存储过程中有三条大概形如这样的语句执行得很慢: select a,b,sum(x) from T group by a,b where …; select c,d,max(y) from T group by c,d where …; select a,c,avg(y),min(z) from T group by a,c where …; 这里的 T 是个有数亿行的巨大表,要分别按三种方式分组,分组的结果集都不大。 分组运算要遍历数据表,这三句 SQL 就要把这个大表遍历三次,对数亿行数据遍历一次的时间就不短,何况三遍。 这种分组运算中,相对于遍历硬盘的时间,CPU 计算时间几乎可以忽略。如果可以在一次遍历中把多种分组汇总都计算出来,虽然 CPU 计算量并没有变少,但能大幅减少硬盘读取数据量,就...
- 下一篇
阿里本地生活端智能架构设计与技术探索
作者:邱灿清(白离) 2018 年 10 月 12 日,阿里巴巴集团宣布正式成立阿里巴巴本地生活服务公司,饿了么和口碑会师合并组成国内领先的本地生活服务平台,使命是“重新定义城市生活,让生活更美好”;口碑专注到店消费服务,饿了么专注到家生活服务,蜂鸟即配专注即时配送服务,客如云专注为商家提供数字化升级的产品和服务,共同推动本地生活市场的数字化,让天下没有难做的生意。 本地生活是阿里巴巴非常重要的业务版图,本文基于阿里巴巴本地生活饿了么APP的业务开发场景,阐述在饿了么APP的业务发展过程中,针对实际的业务场景,通过技术结合业务,是如何发挥端智能在端侧计算决策优势的。 端智能概念 背景 端智能简单说就是在端侧做机器学习或者深度学习模型的推理运行及上层应用,得益于目前手机等硬件设备的发展,强劲的CPU和GPU能够在客户端支持部分高等运算操作(在性能要求下可以牺牲精度),可以将计算工作保留在客户端上进行,从而避免数据上行带宽开销和网络延迟等问题。 智能不管是在云端还是说在终端,解决的问题都是一致的,如何通过将大量数据作为输入源,调整算法策略进行不断学习,推理出最终或者最合适的结论;那么端智能...
相关文章
文章评论
共有0条评论来说两句吧...