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

本文涉及的产品
函数计算FC,每月15万CU 3个月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文提供了一个方案,用不到 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/

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云专有网络VPC使用教程
专有网络VPC可以帮助您基于阿里云构建出一个隔离的网络环境,并可以自定义IP 地址范围、网段、路由表和网关等;此外,也可以通过专线/VPN/GRE等连接方式实现云上VPC与传统IDC的互联,构建混合云业务。 产品详情:https://www.aliyun.com/product/vpc
相关文章
|
6月前
|
Dubbo 前端开发 Java
让你在组建企业级项目时手到擒来——浅谈各类常用工具和框架概述
让你在组建企业级项目时手到擒来——浅谈各类常用工具和框架概述
|
6月前
|
人工智能 自然语言处理 搜索推荐
AI原生企业级Agent构建平台具备哪些特性?一篇文章看明白
AI原生企业级Agent构建平台有哪些特性?澜码正式发布AskXBOT平台为业界揭晓答案。
474 0
|
3月前
|
IDE 前端开发 数据库
OpenSumi开源问题之OpenSumi的定义如何解决
OpenSumi开源问题之OpenSumi的定义如何解决
|
3月前
|
监控 Linux 数据库连接
手把手教你从本地到云端:全面解析Blazor应用的部署流程与最佳实践,助你轻松掌握发布Blazor WebAssembly应用到Azure的每一个细节
【8月更文挑战第31天】本文详细介绍了将 Blazor 应用从本地部署到 Azure 的全过程。首先确保已在 Visual Studio 中创建 Blazor WebAssembly 应用,接着清理项目并配置发布选项。然后在 Azure 中创建 App Service 并完成应用部署。最后,配置环境变量、SSL 和监控,确保应用稳定运行。附带示例代码,展示如何加载和使用 Azure 环境变量。通过最佳实践指导,帮助你顺利完成 Blazor 应用的云端部署。
89 0
|
4月前
|
分布式计算 API 对象存储
Ray是一个开源的分布式计算框架,用于构建和扩展分布式应用。它提供了简单的API,使得开发者可以轻松地编写并行和分布式代码,而无需担心底层的复杂性。
Ray是一个开源的分布式计算框架,用于构建和扩展分布式应用。它提供了简单的API,使得开发者可以轻松地编写并行和分布式代码,而无需担心底层的复杂性。
835 11
|
Kubernetes Cloud Native Dubbo
Higress 开源后,我们整理了开发者最关心的 15 个问题
云原生网关 Higress 开源后,引起了开发者们的热烈讨论,我们整理了大家在 GitHub、钉群、微信群讨论的问题,并将回答汇总如下,方便各位更准确的读懂 Higress,也非常欢迎您和我们一起共建、定义 Higress。
344 7
Higress 开源后,我们整理了开发者最关心的 15 个问题
|
存储 JavaScript 物联网
【无服务器架构】openwhisk 经典使用案例
【无服务器架构】openwhisk 经典使用案例
|
SQL JSON Kubernetes
KubeVela 项目和能力简介 | 学习笔记
快速学习 KubeVela 项目和能力简介
KubeVela 项目和能力简介 | 学习笔记
|
Kubernetes Cloud Native 安全
Higress 开源后,我们整理了开发者最关心的15个问题
云原生架构下,网关承载着流量管理、服务调用、安全管理等多重职能,在稳定性、性能、安全性、易用性上存在着更高的要求。在 CNCF Landscpae 编排和管理的 API Gateway 领域中,已经有不少开源的网关选择,开发者们也有着不小的选型诉求。
Higress 开源后,我们整理了开发者最关心的15个问题
|
运维 Cloud Native API
KubeVela 插件指南:轻松扩展你的平台专属能力
本文作者为 KubeVela 社区贡献者 姜洪烨。 我在原文基础上做了适量修改。KubeVela 插件(addon)可以方便地扩展 KubeVela 的能力。正如我们所知,KubeVela 是一个微内核高度可扩展的平台,用户可以通过 模块定义(Definition)扩展 KubeVela 的系统能力,而 KubeVela 插件正是方便将这些自定义扩展及其依赖打包并分发的核心功能。不仅如此,Kube
KubeVela 插件指南:轻松扩展你的平台专属能力
下一篇
无影云桌面