From 1a7db89fbda492cee459eb339cb1a8b24713eee7 Mon Sep 17 00:00:00 2001 From: yangsoon Date: Wed, 4 Aug 2021 20:23:56 +0800 Subject: [PATCH] add ocm demo (#1992) --- .../vela-core/templates/addons/terraform.yaml | 270 ++++++++++++++++++ docs/examples/workflow-with-ocm/README.md | 112 ++++++++ docs/examples/workflow-with-ocm/app.yaml | 39 +++ .../definitions/create-ack.yaml | 57 ++++ .../definitions/deploy2cluster.yaml | 23 ++ .../definitions/envbinding.yaml | 49 ++++ .../definitions/register-cluster.yaml | 191 +++++++++++++ .../hack/prepare-alibaba-credentials.sh | 6 + .../initializers/init-managed-cluster.yaml | 37 +++ .../initializers/init-terraform-alibaba.yaml | 36 +++ vela-templates/addons/auto-gen/terraform.yaml | 270 ++++++++++++++++++ .../terraform/definitions/alibaba-ack.yaml | 208 ++++++++++++++ .../terraform/definitions/alibaba-oss.yaml | 32 +++ .../terraform/definitions/alibaba-rds.yaml | 55 ++++ 14 files changed, 1385 insertions(+) create mode 100644 docs/examples/workflow-with-ocm/README.md create mode 100644 docs/examples/workflow-with-ocm/app.yaml create mode 100644 docs/examples/workflow-with-ocm/definitions/create-ack.yaml create mode 100644 docs/examples/workflow-with-ocm/definitions/deploy2cluster.yaml create mode 100644 docs/examples/workflow-with-ocm/definitions/envbinding.yaml create mode 100644 docs/examples/workflow-with-ocm/definitions/register-cluster.yaml create mode 100644 docs/examples/workflow-with-ocm/hack/prepare-alibaba-credentials.sh create mode 100644 docs/examples/workflow-with-ocm/initializers/init-managed-cluster.yaml create mode 100644 docs/examples/workflow-with-ocm/initializers/init-terraform-alibaba.yaml create mode 100644 vela-templates/addons/terraform/definitions/alibaba-ack.yaml create mode 100644 vela-templates/addons/terraform/definitions/alibaba-oss.yaml create mode 100644 vela-templates/addons/terraform/definitions/alibaba-rds.yaml diff --git a/charts/vela-core/templates/addons/terraform.yaml b/charts/vela-core/templates/addons/terraform.yaml index 5b6bad699..16aafbfff 100644 --- a/charts/vela-core/templates/addons/terraform.yaml +++ b/charts/vela-core/templates/addons/terraform.yaml @@ -26,6 +26,276 @@ data: metadata: name: terraform-system type: raw + - name: alibaba-ack + properties: + apiVersion: core.oam.dev/v1beta1 + kind: ComponentDefinition + metadata: + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba + Cloud ACK cluster + type: terraform + name: alibaba-ack + namespace: vela-system + spec: + schematic: + terraform: + configuration: | + module "kubernetes" { + source = "github.com/zzxwill/terraform-alicloud-kubernetes" + new_nat_gateway = true + vpc_name = var.vpc_name + vpc_cidr = var.vpc_cidr + vswitch_name_prefix = var.vswitch_name_prefix + vswitch_cidrs = var.vswitch_cidrs + master_instance_types = var.master_instance_types + worker_instance_types = var.worker_instance_types + k8s_pod_cidr = var.k8s_pod_cidr + k8s_service_cidr = var.k8s_service_cidr + k8s_worker_number = var.k8s_worker_number + cpu_core_count = var.cpu_core_count + memory_size = var.memory_size + zone_id = var.zone_id + k8s_version = var.k8s_version + k8s_name_prefix = var.k8s_name_prefix + } + ###################### + # Instance types variables + ###################### + variable "cpu_core_count" { + description = "CPU core count is used to fetch instance types." + type = number + default = 4 + } + variable "memory_size" { + description = "Memory size used to fetch instance types." + type = number + default = 8 + } + ###################### + # VPC variables + ###################### + variable "vpc_name" { + description = "The vpc name used to create a new vpc when 'vpc_id' is not specified. Default to variable `example_name`" + type = string + default = "tf-k8s-vpc" + } + variable "vpc_cidr" { + description = "The cidr block used to launch a new vpc when 'vpc_id' is not specified." + type = string + default = "10.0.0.0/8" + } + ###################### + # VSwitch variables + ###################### + variable "vswitch_name_prefix" { + type = string + description = "The vswitch name prefix used to create several new vswitches. Default to variable 'example_name'." + default = "tf-k8s-vsw" + } + variable "number_format" { + description = "The number format used to output." + type = string + default = "%02d" + } + variable "vswitch_ids" { + description = "List of existing vswitch id." + type = list + default = [] + } + variable "vswitch_cidrs" { + description = "List of cidr blocks used to create several new vswitches when 'vswitch_ids' is not specified." + type = list + default = [ + "10.1.0.0/16", + "10.2.0.0/16", + "10.3.0.0/16"] + } + variable "k8s_name_prefix" { + description = "The name prefix used to create several kubernetes clusters. Default to variable `example_name`" + type = string + default = "poc" + } + variable "new_nat_gateway" { + type = bool + description = "Whether to create a new nat gateway. In this template, a new nat gateway will create a nat gateway, eip and server snat entries." + default = true + } + variable "master_instance_types" { + description = "The ecs instance types used to launch master nodes." + type = list + default = [ + # hongkong + "ecs.sn1ne.xlarge", + # hongkong + "ecs.c6.xlarge", + # hongkong + "ecs.c4.xlarge", + # hongkong + "ecs.c5.xlarge", + "ecs.n4.xlarge", + # "ecs.n1.large", + # "ecs.sn1.large", + # "ecs.s6-c1m2.xlarge", + # "ecs.c6e.xlarge" + ] + } + variable "worker_instance_types" { + description = "The ecs instance types used to launch worker nodes." + type = list + default = [ + # hongkong + "ecs.sn1ne.xlarge", + # hongkong + "ecs.c6.xlarge", + # hongkong + "ecs.c4.xlarge", + # hongkong + "ecs.c6e.xlarge", + "ecs.n4.xlarge", + // "ecs.n1.large", + // "ecs.sn1.large", + // "ecs.s6-c1m2.xlarge" + ] + } + variable "node_cidr_mask" { + type = number + description = "The node cidr block to specific how many pods can run on single node. Valid values: [24-28]." + default = 24 + } + variable "enable_ssh" { + description = "Enable login to the node through SSH." + type = bool + default = true + } + variable "install_cloud_monitor" { + description = "Install cloud monitor agent on ECS." + type = bool + default = true + } + variable "cpu_policy" { + type = string + description = "kubelet cpu policy. Valid values: 'none','static'. Default to 'none'." + default = "none" + } + variable "proxy_mode" { + description = "Proxy mode is option of kube-proxy. Valid values: 'ipvs','iptables'. Default to 'iptables'." + type = string + default = "iptables" + } + variable "password" { + description = "The password of ECS instance." + type = string + default = "Just4Test" + } + variable "k8s_worker_number" { + description = "The number of worker nodes in kubernetes cluster." + type = number + default = 2 + } + # k8s_pod_cidr is only for flannel network + variable "k8s_pod_cidr" { + description = "The kubernetes pod cidr block. It cannot be equals to vpc's or vswitch's and cannot be in them." + type = string + default = "172.20.0.0/16" + } + variable "k8s_service_cidr" { + description = "The kubernetes service cidr block. It cannot be equals to vpc's or vswitch's or pod's and cannot be in them." + type = string + default = "192.168.0.0/16" + } + variable "k8s_version" { + description = "The version of the kubernetes version. Valid values: '1.16.6-aliyun.1','1.14.8-aliyun.1'. Default to '1.16.6-aliyun.1'." + type = string + default = "1.20.4-aliyun.1" + } + variable "zone_id" { + description = "Availability Zone ID" + type = string + default = "cn-hongkong-b" + # "cn-beijing-a" + } + output "name" { + value = module.kubernetes.name + } + output "kubeconfig" { + value = module.kubernetes.kubeconfig + } + output "cluster_ca_cert" { + value = module.kubernetes.cluster_ca_cert + } + output "client_cert" { + value = module.kubernetes.client_cert + } + output "client_key" { + value = module.kubernetes.client_key + } + output "api_server_internet" { + value = module.kubernetes.api_server_internet + } + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + type: raw + - name: alibaba-oss + properties: + apiVersion: core.oam.dev/v1alpha2 + kind: ComponentDefinition + metadata: + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba + Cloud OSS object + type: terraform + name: alibaba-oss + spec: + schematic: + terraform: + configuration: "resource \"alicloud_oss_bucket\" \"bucket-acl\" {\n + \ bucket = var.bucket\n acl = var.acl\n}\noutput \"BUCKET_NAME\" + {\n value = \"${alicloud_oss_bucket.bucket-acl.bucket}.${alicloud_oss_bucket.bucket-acl.extranet_endpoint}\"\n}\nvariable + \"bucket\" {\n description = \"OSS bucket name\"\n default = \"vela-website\"\n + \ type = string\n}\nvariable \"acl\" {\n description = \"OSS bucket + ACL, supported 'private', 'public-read', 'public-read-write'\"\n + \ default = \"private\"\n type = string\n} \n" + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + type: raw + - name: alibaba-rds + properties: + apiVersion: core.oam.dev/v1alpha2 + kind: ComponentDefinition + metadata: + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba + Cloud RDS object + type: terraform + name: alibaba-rds + spec: + schematic: + terraform: + configuration: "module \"rds\" {\n source = \"terraform-alicloud-modules/rds/alicloud\"\n + \ engine = \"MySQL\"\n engine_version = \"8.0\"\n instance_type + = \"rds.mysql.c1.large\"\n instance_storage = \"20\"\n instance_name + = var.instance_name\n account_name = var.account_name\n password + = var.password\n}\noutput \"DB_NAME\" {\n value = module.rds.this_db_instance_name\n}\noutput + \"DB_USER\" {\n value = module.rds.this_db_database_account\n}\noutput + \"DB_PORT\" {\n value = module.rds.this_db_instance_port\n}\noutput + \"DB_HOST\" {\n value = module.rds.this_db_instance_connection_string\n}\noutput + \"DB_PASSWORD\" {\n value = module.rds.this_db_instance_port\n}\nvariable + \"instance_name\" {\n description = \"RDS instance name\"\n type + = string\n default = \"poc\"\n}\nvariable \"account_name\" {\n + \ description = \"RDS instance user account name\"\n type = string\n + \ default = \"oam\"\n}\nvariable \"password\" {\n description = + \"RDS instance account password\"\n type = string\n default = + \"Xyfff83jfewGGfaked\"\n} \n" + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + type: raw status: rollout: batchRollingState: "" diff --git a/docs/examples/workflow-with-ocm/README.md b/docs/examples/workflow-with-ocm/README.md new file mode 100644 index 000000000..dfe2f0687 --- /dev/null +++ b/docs/examples/workflow-with-ocm/README.md @@ -0,0 +1,112 @@ +# WorkFlow with OCM + +In this tutorial, you will create an ack cluster as a production environment and deploy the configured app +to this production environment. + +## Prerequisites + +- In order to follow the guide, you will need a Kubernetes cluster version 1.20+ as control-plane cluster, and +the cluster's APIServer has an external IP. + +- Store the AK/AS of Alibaba Cloud to the Secret. + + ```shell + export ALICLOUD_ACCESS_KEY=xxx; export ALICLOUD_SECRET_KEY=yyy + ``` + + ```shell + # If you'd like to use Alicloud Security Token Service, also export `ALICLOUD_SECURITY_TOKEN`. + export ALICLOUD_SECURITY_TOKEN=zzz + ``` + + ```shell + sh hack/prepare-alibaba-credentials.sh + ``` + + ```shell + $ kubectl get secret -n vela-system + NAME TYPE DATA AGE + alibaba-account-creds Opaque 1 11s + ``` + +- Install Definitions + ```shell + kubectl apply -f definitions + ``` + +## Create Initializer terraform-alibaba + +Initializer terraform-alibaba will create an environment which allows users use terraform to create cloud resource on aliyun. + +```shell +kubectl apply -f initializers/init-terraform-alibaba.yaml +``` + +It will take few minutes to wait the `PHASE` of Initializer `terraform-alibaba` to be `success`. + +```shell +$ kubectl get initializers.core.oam.dev -n vela-system +NAMESPACE NAME PHASE AGE +vela-system terraform-alibaba success 94s +``` + +## Create Initializer managed-cluster + +Initializer managed-cluster can create an ack cluster and use OCM to manage the cluster. + +1. You should set the `hubAPIServer` to the public network address in `init-managed-cluster.yaml` +```yaml +# init-managed-cluster.yaml +- name: register-ack + type: register-cluster + inputs: + ... + properties: + # user should set public network address of your control-plane cluster APIServer + hubAPIServer: {{ public network address of APIServer }} +``` + +2. Apply the Initializer managed-cluster +```shell +kubectl apply -f initializers/init-managed-cluster.yaml +``` + +It will take 15 to 20 minutes to create an ack cluster, please wait until the status of `managed-cluster` to be `success`. + +```shell +$ kubectl get initializers.core.oam.dev -n vela-system +NAMESPACE NAME PHASE AGE +vela-system managed-cluster success 45m +``` + +3. Check the new ack cluster has been registered + +```shell +$ kubectl get managedclusters.cluster.open-cluster-management.io +NAME HUB ACCEPTED MANAGED CLUSTER URLS JOINED AVAILABLE AGE +poc-01 true {{ APIServer address }} True True 30s +``` + + +## Deploy the resource to ack cluster + +```shell +kubectl apply -f app.yaml +``` + +check the app `workflow-demo` was created successfully + +```shell +$ kubectl get app workflow-demo +NAME COMPONENT TYPE PHASE HEALTHY STATUS AGE +workflow-demo nginx-server webservice running true 7s +``` + +use kubectl connect to the managed-cluster `poc-01` and check the resources in the app +are successfully deployed to the cluster `poc-01`. + +```shell +$ kubectl get deployments +NAME READY UP-TO-DATE AVAILABLE AGE +nginx-server 1/1 1 1 40s +``` \ No newline at end of file diff --git a/docs/examples/workflow-with-ocm/app.yaml b/docs/examples/workflow-with-ocm/app.yaml new file mode 100644 index 000000000..096cc32ec --- /dev/null +++ b/docs/examples/workflow-with-ocm/app.yaml @@ -0,0 +1,39 @@ +apiVersion: core.oam.dev/v1beta1 +kind: Application +metadata: + name: workflow-demo + namespace: default +spec: + components: + - name: nginx-server + type: webservice + properties: + image: nginx:1.21 + port: 80 + + policies: + - name: patch + type: env-binding + properties: + envs: + - name: prod + patch: + components: + - name: nginx-server + type: webservice + properties: + image: nginx:1.20 + port: 80 + placement: + clusterSelector: + labels: + purpose: test + + workflow: + steps: + - name: deploy-server + type: deploy2cluster + properties: + env: prod + policy: patch + component: nginx-server \ No newline at end of file diff --git a/docs/examples/workflow-with-ocm/definitions/create-ack.yaml b/docs/examples/workflow-with-ocm/definitions/create-ack.yaml new file mode 100644 index 000000000..2f989a995 --- /dev/null +++ b/docs/examples/workflow-with-ocm/definitions/create-ack.yaml @@ -0,0 +1,57 @@ +apiVersion: core.oam.dev/v1beta1 +kind: WorkflowStepDefinition +metadata: + name: create-ack + namespace: vela-system +spec: + schematic: + cue: + template: | + import ( + "vela/op" + "encoding/base64" + ) + + configuration: op.#Load & { + component: parameter.component + } + + apply: op.#Apply & { + value: { + configuration.value.workload + } + } + + wait: op.#ConditionalWait & { + continue: apply.value.status.state == "Available" + } + + secretName: apply.value.spec.writeConnectionSecretToRef.name + secretNamespace: apply.value.spec.writeConnectionSecretToRef.namespace + + ackConn: op.#Read & { + value: { + apiVersion: "v1" + kind: "Secret" + metadata: { + name: secretName + namespace: secretNamespace + } + } + } + + parameter: { + component: string + } + + connInfo: { + clusterName: base64.Decode(null, ackConn.value.data["name"]) + clusterCACert: base64.Decode(null, ackConn.value.data["cluster_ca_cert"]) + clientCert: base64.Decode(null, ackConn.value.data["client_cert"]) + clientKey: base64.Decode(null, ackConn.value.data["client_key"]) + clusterAPIServer: base64.Decode(null, ackConn.value.data["api_server_internet"]) + } + + + + diff --git a/docs/examples/workflow-with-ocm/definitions/deploy2cluster.yaml b/docs/examples/workflow-with-ocm/definitions/deploy2cluster.yaml new file mode 100644 index 000000000..3d84cd1b2 --- /dev/null +++ b/docs/examples/workflow-with-ocm/definitions/deploy2cluster.yaml @@ -0,0 +1,23 @@ +apiVersion: core.oam.dev/v1beta1 +kind: WorkflowStepDefinition +metadata: + name: deploy2cluster + namespace: vela-system +spec: + schematic: + cue: + template: | + import ("vela/op") + + component: op.#ApplyEnvBindComponent & { + env: parameter.env + policy: parameter.policy + component: parameter.component + namespace: context.namespace + } + parameter: { + env: string + policy: string + component: string + } + diff --git a/docs/examples/workflow-with-ocm/definitions/envbinding.yaml b/docs/examples/workflow-with-ocm/definitions/envbinding.yaml new file mode 100644 index 000000000..0008a5d55 --- /dev/null +++ b/docs/examples/workflow-with-ocm/definitions/envbinding.yaml @@ -0,0 +1,49 @@ +apiVersion: core.oam.dev/v1beta1 +kind: PolicyDefinition +metadata: + name: env-binding + namespace: vela-system +spec: + schematic: + cue: + template: | + output: { + apiVersion: "core.oam.dev/v1alpha1" + kind: "EnvBinding" + spec: { + engine: parameter.engine + appTemplate: { + apiVersion: "core.oam.dev/v1beta1" + kind: "Application" + metadata: { + name: context.appName + namespace: context.namespace + } + spec: { + components: context.components + } + } + envs: parameter.envs + } + } + + #Env: { + name: string + patch: components: [...{ + name: string + type: string + properties: {...} + }] + placement: clusterSelector: { + labels?: [string]: string + name?: string + } + } + + parameter: { + engine: *"ocm" | string + envs: [...#Env] + } + + + diff --git a/docs/examples/workflow-with-ocm/definitions/register-cluster.yaml b/docs/examples/workflow-with-ocm/definitions/register-cluster.yaml new file mode 100644 index 000000000..e28fbfeda --- /dev/null +++ b/docs/examples/workflow-with-ocm/definitions/register-cluster.yaml @@ -0,0 +1,191 @@ +apiVersion: core.oam.dev/v1beta1 +kind: WorkflowStepDefinition +metadata: + name: register-cluster + namespace: vela-system +spec: + schematic: + cue: + template: | + import ("vela/op") + + clusterrole: op.#Apply & { + value: { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRole" + metadata: { + name: "cluster-register" + } + rules: [{ + apiGroups: [""] + resources: ["configmaps", "namespaces", "serviceaccounts", "services", "secrets"] + verbs: ["create", "get", "list", "update", "watch", "patch", "delete"] + }, { + apiGroups: ["", "events.k8s.io"] + resources: ["events"] + verbs: ["create", "update", "patch"] + }, { + apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterrolebindings", "rolebindings"] + verbs: ["create", "get", "list", "update", "watch", "patch", "delete"] + }, { + apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles", "roles"] + verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "escalate", "bind"] + }, { + apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles", "roles"] + verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "escalate", "bind"] + }, { + apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests"] + verbs: ["create", "get", "list", "watch"] + }, { + apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests/approval"] + verbs: ["update"] + }, { + apiGroups: ["certificates.k8s.io"] + resources: ["signers"] + resourceNames: ["kubernetes.io/*"] + verbs: ["approve"] + }, { + apiGroups: ["cluster.open-cluster-management.io"] + resources: ["managedclusters"] + verbs: ["create", "get", "list", "update", "watch", "delete"] + }, { + apiGroups: ["register.open-cluster-management.io"] + resources: ["managedclusters", "managedclusters/accept"] + verbs: ["create", "get", "list", "update", "watch", "delete"] + }] + } + } + + serviceaccount: op.#Apply & { + value: { + apiVersion: "v1" + kind: "ServiceAccount" + metadata: { + name: "cluster-register" + namespace: "default" + } + } + } + + rolebinding: op.#Apply & { + value: { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRoleBinding" + metadata: { + name: "cluster-register" + } + roleRef: { + apiGroup: "rbac.authorization.k8s.io" + kind: "ClusterRole" + name: "cluster-register" + } + subjects: [{ + kind: "ServiceAccount" + name: "cluster-register" + namespace: "default" + }] + } + } + + register: op.#Apply & { + value: { + apiVersion: "batch/v1" + kind: "Job" + metadata: { + name: "cluster-register" + namespace: "default" + } + spec: { + template: { + spec: { + containers: [{ + name: "cluster-register" + image: "oamdev/cluster-register:v1.0" + imagePullPolicy: "Always" + command: [ + "/app", "--cluster-name=" + "\(parameter.connInfo.clusterName)", + "--hub-api-server=" + "\(parameter.hubAPIServer)", + "--cluster-ca-cert=" + "\(parameter.connInfo.clusterCACert)", + "--client-cert=" + "\(parameter.connInfo.clientCert)", + "--client-key=" + "\(parameter.connInfo.clientKey)", + "--api-server-internet=" + "\(parameter.connInfo.clusterAPIServer)", + "--kube-config=" + "\(parameter.connInfo.kubeConfig)", + ] + }] + restartPolicy: "OnFailure" + serviceAccountName: "cluster-register" + } + } + } + } + } + + wait: op.#ConditionalWait & { + continue: register.value.status.succeeded == 1 + } + + clusterSet: op.#Apply & { + value: { + apiVersion: "cluster.open-cluster-management.io/v1alpha1" + kind: "ManagedClusterSet" + metadata: name: parameter.env + } + } + + clusterSetBinding: op.#Apply & { + value: { + apiVersion: "cluster.open-cluster-management.io/v1alpha1" + kind: "ManagedClusterSetBinding" + metadata: { + name: parameter.env + namespace: parameter.initNameSpace + } + spec: clusterSet: parameter.env + } + } + + managedCluster: op.#Read & { + value: { + apiVersion: "cluster.open-cluster-management.io/v1" + kind: "ManagedCluster" + metadata: { + name: parameter.connInfo.clusterName + } + } + } + + patchManagedCluster: op.#Apply & { + value: { + managedCluster.value + metadata: labels: { + "cluster.open-cluster-management.io/clusterset": parameter.env + } + metadata: labels: parameter.patchLabels + } + } + + parameter: { + env: string + initNameSpace: *"default" | string + patchLabels: [string]: string + hubAPIServer: *"" | string + connInfo: { + clusterName: string + clusterCACert: *"" | string + clientCert: *"" | string + clientKey: *"" | string + clusterAPIServer: *"" | string + kubeConfig: *"" | string + } + } + + + + + + diff --git a/docs/examples/workflow-with-ocm/hack/prepare-alibaba-credentials.sh b/docs/examples/workflow-with-ocm/hack/prepare-alibaba-credentials.sh new file mode 100644 index 000000000..cf6dacede --- /dev/null +++ b/docs/examples/workflow-with-ocm/hack/prepare-alibaba-credentials.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +echo "accessKeyID: ${ALICLOUD_ACCESS_KEY}\naccessKeySecret: ${ALICLOUD_SECRET_KEY}\nsecurityToken: ${ALICLOUD_SECURITY_TOKEN}" > alibaba-credentials.conf +kubectl create namespace vela-system +kubectl create secret generic alibaba-account-creds -n vela-system --from-file=credentials=alibaba-credentials.conf +rm -f alibaba-credentials.conf \ No newline at end of file diff --git a/docs/examples/workflow-with-ocm/initializers/init-managed-cluster.yaml b/docs/examples/workflow-with-ocm/initializers/init-managed-cluster.yaml new file mode 100644 index 000000000..f67aefb14 --- /dev/null +++ b/docs/examples/workflow-with-ocm/initializers/init-managed-cluster.yaml @@ -0,0 +1,37 @@ +apiVersion: core.oam.dev/v1beta1 +kind: Initializer +metadata: + name: managed-cluster + namespace: vela-system +spec: + appTemplate: + spec: + components: + - name: ack-worker + type: alibaba-ack + properties: + writeConnectionSecretToRef: + name: ack-conn + namespace: vela-system + workflow: + steps: + - name: terraform-ack + type: create-ack + properties: + component: ack-worker + outputs: + - name: connInfo + exportKey: connInfo + + - name: register-ack + type: register-cluster + inputs: + - from: connInfo + parameterKey: connInfo + properties: + # user should set public network address of APIServer + hubAPIServer: {{ public network address of APIServer }} + env: prod + initNameSpace: default + patchLabels: + purpose: test diff --git a/docs/examples/workflow-with-ocm/initializers/init-terraform-alibaba.yaml b/docs/examples/workflow-with-ocm/initializers/init-terraform-alibaba.yaml new file mode 100644 index 000000000..6860d98d6 --- /dev/null +++ b/docs/examples/workflow-with-ocm/initializers/init-terraform-alibaba.yaml @@ -0,0 +1,36 @@ +apiVersion: core.oam.dev/v1beta1 +kind: Initializer +metadata: + name: terraform-alibaba + namespace: vela-system +spec: + appTemplate: + spec: + components: + - name: default + type: raw + properties: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Provider + metadata: + namespace: default + spec: + provider: alibaba + region: cn-hongkong + credentials: + source: Secret + secretRef: + namespace: vela-system + name: alibaba-account-creds + key: credentials + dependsOn: + - ref: + apiVersion: core.oam.dev/v1beta1 + kind: Initializer + name: terraform + namespace: vela-system + - ref: + apiVersion: core.oam.dev/v1beta1 + kind: Initializer + name: ocm-cluster-manager + namespace: vela-system \ No newline at end of file diff --git a/vela-templates/addons/auto-gen/terraform.yaml b/vela-templates/addons/auto-gen/terraform.yaml index 06a8e829b..366bf8fd1 100644 --- a/vela-templates/addons/auto-gen/terraform.yaml +++ b/vela-templates/addons/auto-gen/terraform.yaml @@ -23,6 +23,276 @@ spec: metadata: name: terraform-system type: raw + - name: alibaba-ack + properties: + apiVersion: core.oam.dev/v1beta1 + kind: ComponentDefinition + metadata: + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba + Cloud ACK cluster + type: terraform + name: alibaba-ack + namespace: vela-system + spec: + schematic: + terraform: + configuration: | + module "kubernetes" { + source = "github.com/zzxwill/terraform-alicloud-kubernetes" + new_nat_gateway = true + vpc_name = var.vpc_name + vpc_cidr = var.vpc_cidr + vswitch_name_prefix = var.vswitch_name_prefix + vswitch_cidrs = var.vswitch_cidrs + master_instance_types = var.master_instance_types + worker_instance_types = var.worker_instance_types + k8s_pod_cidr = var.k8s_pod_cidr + k8s_service_cidr = var.k8s_service_cidr + k8s_worker_number = var.k8s_worker_number + cpu_core_count = var.cpu_core_count + memory_size = var.memory_size + zone_id = var.zone_id + k8s_version = var.k8s_version + k8s_name_prefix = var.k8s_name_prefix + } + ###################### + # Instance types variables + ###################### + variable "cpu_core_count" { + description = "CPU core count is used to fetch instance types." + type = number + default = 4 + } + variable "memory_size" { + description = "Memory size used to fetch instance types." + type = number + default = 8 + } + ###################### + # VPC variables + ###################### + variable "vpc_name" { + description = "The vpc name used to create a new vpc when 'vpc_id' is not specified. Default to variable `example_name`" + type = string + default = "tf-k8s-vpc" + } + variable "vpc_cidr" { + description = "The cidr block used to launch a new vpc when 'vpc_id' is not specified." + type = string + default = "10.0.0.0/8" + } + ###################### + # VSwitch variables + ###################### + variable "vswitch_name_prefix" { + type = string + description = "The vswitch name prefix used to create several new vswitches. Default to variable 'example_name'." + default = "tf-k8s-vsw" + } + variable "number_format" { + description = "The number format used to output." + type = string + default = "%02d" + } + variable "vswitch_ids" { + description = "List of existing vswitch id." + type = list + default = [] + } + variable "vswitch_cidrs" { + description = "List of cidr blocks used to create several new vswitches when 'vswitch_ids' is not specified." + type = list + default = [ + "10.1.0.0/16", + "10.2.0.0/16", + "10.3.0.0/16"] + } + variable "k8s_name_prefix" { + description = "The name prefix used to create several kubernetes clusters. Default to variable `example_name`" + type = string + default = "poc" + } + variable "new_nat_gateway" { + type = bool + description = "Whether to create a new nat gateway. In this template, a new nat gateway will create a nat gateway, eip and server snat entries." + default = true + } + variable "master_instance_types" { + description = "The ecs instance types used to launch master nodes." + type = list + default = [ + # hongkong + "ecs.sn1ne.xlarge", + # hongkong + "ecs.c6.xlarge", + # hongkong + "ecs.c4.xlarge", + # hongkong + "ecs.c5.xlarge", + "ecs.n4.xlarge", + # "ecs.n1.large", + # "ecs.sn1.large", + # "ecs.s6-c1m2.xlarge", + # "ecs.c6e.xlarge" + ] + } + variable "worker_instance_types" { + description = "The ecs instance types used to launch worker nodes." + type = list + default = [ + # hongkong + "ecs.sn1ne.xlarge", + # hongkong + "ecs.c6.xlarge", + # hongkong + "ecs.c4.xlarge", + # hongkong + "ecs.c6e.xlarge", + "ecs.n4.xlarge", + // "ecs.n1.large", + // "ecs.sn1.large", + // "ecs.s6-c1m2.xlarge" + ] + } + variable "node_cidr_mask" { + type = number + description = "The node cidr block to specific how many pods can run on single node. Valid values: [24-28]." + default = 24 + } + variable "enable_ssh" { + description = "Enable login to the node through SSH." + type = bool + default = true + } + variable "install_cloud_monitor" { + description = "Install cloud monitor agent on ECS." + type = bool + default = true + } + variable "cpu_policy" { + type = string + description = "kubelet cpu policy. Valid values: 'none','static'. Default to 'none'." + default = "none" + } + variable "proxy_mode" { + description = "Proxy mode is option of kube-proxy. Valid values: 'ipvs','iptables'. Default to 'iptables'." + type = string + default = "iptables" + } + variable "password" { + description = "The password of ECS instance." + type = string + default = "Just4Test" + } + variable "k8s_worker_number" { + description = "The number of worker nodes in kubernetes cluster." + type = number + default = 2 + } + # k8s_pod_cidr is only for flannel network + variable "k8s_pod_cidr" { + description = "The kubernetes pod cidr block. It cannot be equals to vpc's or vswitch's and cannot be in them." + type = string + default = "172.20.0.0/16" + } + variable "k8s_service_cidr" { + description = "The kubernetes service cidr block. It cannot be equals to vpc's or vswitch's or pod's and cannot be in them." + type = string + default = "192.168.0.0/16" + } + variable "k8s_version" { + description = "The version of the kubernetes version. Valid values: '1.16.6-aliyun.1','1.14.8-aliyun.1'. Default to '1.16.6-aliyun.1'." + type = string + default = "1.20.4-aliyun.1" + } + variable "zone_id" { + description = "Availability Zone ID" + type = string + default = "cn-hongkong-b" + # "cn-beijing-a" + } + output "name" { + value = module.kubernetes.name + } + output "kubeconfig" { + value = module.kubernetes.kubeconfig + } + output "cluster_ca_cert" { + value = module.kubernetes.cluster_ca_cert + } + output "client_cert" { + value = module.kubernetes.client_cert + } + output "client_key" { + value = module.kubernetes.client_key + } + output "api_server_internet" { + value = module.kubernetes.api_server_internet + } + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + type: raw + - name: alibaba-oss + properties: + apiVersion: core.oam.dev/v1alpha2 + kind: ComponentDefinition + metadata: + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba + Cloud OSS object + type: terraform + name: alibaba-oss + spec: + schematic: + terraform: + configuration: "resource \"alicloud_oss_bucket\" \"bucket-acl\" {\n + \ bucket = var.bucket\n acl = var.acl\n}\noutput \"BUCKET_NAME\" + {\n value = \"${alicloud_oss_bucket.bucket-acl.bucket}.${alicloud_oss_bucket.bucket-acl.extranet_endpoint}\"\n}\nvariable + \"bucket\" {\n description = \"OSS bucket name\"\n default = \"vela-website\"\n + \ type = string\n}\nvariable \"acl\" {\n description = \"OSS bucket + ACL, supported 'private', 'public-read', 'public-read-write'\"\n + \ default = \"private\"\n type = string\n} \n" + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + type: raw + - name: alibaba-rds + properties: + apiVersion: core.oam.dev/v1alpha2 + kind: ComponentDefinition + metadata: + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba + Cloud RDS object + type: terraform + name: alibaba-rds + spec: + schematic: + terraform: + configuration: "module \"rds\" {\n source = \"terraform-alicloud-modules/rds/alicloud\"\n + \ engine = \"MySQL\"\n engine_version = \"8.0\"\n instance_type + = \"rds.mysql.c1.large\"\n instance_storage = \"20\"\n instance_name + = var.instance_name\n account_name = var.account_name\n password + = var.password\n}\noutput \"DB_NAME\" {\n value = module.rds.this_db_instance_name\n}\noutput + \"DB_USER\" {\n value = module.rds.this_db_database_account\n}\noutput + \"DB_PORT\" {\n value = module.rds.this_db_instance_port\n}\noutput + \"DB_HOST\" {\n value = module.rds.this_db_instance_connection_string\n}\noutput + \"DB_PASSWORD\" {\n value = module.rds.this_db_instance_port\n}\nvariable + \"instance_name\" {\n description = \"RDS instance name\"\n type + = string\n default = \"poc\"\n}\nvariable \"account_name\" {\n + \ description = \"RDS instance user account name\"\n type = string\n + \ default = \"oam\"\n}\nvariable \"password\" {\n description = + \"RDS instance account password\"\n type = string\n default = + \"Xyfff83jfewGGfaked\"\n} \n" + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + type: raw status: rollout: batchRollingState: "" diff --git a/vela-templates/addons/terraform/definitions/alibaba-ack.yaml b/vela-templates/addons/terraform/definitions/alibaba-ack.yaml new file mode 100644 index 000000000..d04c57ba0 --- /dev/null +++ b/vela-templates/addons/terraform/definitions/alibaba-ack.yaml @@ -0,0 +1,208 @@ +apiVersion: core.oam.dev/v1beta1 +kind: ComponentDefinition +metadata: + name: alibaba-ack + namespace: vela-system + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba Cloud ACK cluster + type: terraform +spec: + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + schematic: + terraform: + configuration: | + module "kubernetes" { + source = "github.com/zzxwill/terraform-alicloud-kubernetes" + new_nat_gateway = true + vpc_name = var.vpc_name + vpc_cidr = var.vpc_cidr + vswitch_name_prefix = var.vswitch_name_prefix + vswitch_cidrs = var.vswitch_cidrs + master_instance_types = var.master_instance_types + worker_instance_types = var.worker_instance_types + k8s_pod_cidr = var.k8s_pod_cidr + k8s_service_cidr = var.k8s_service_cidr + k8s_worker_number = var.k8s_worker_number + cpu_core_count = var.cpu_core_count + memory_size = var.memory_size + zone_id = var.zone_id + k8s_version = var.k8s_version + k8s_name_prefix = var.k8s_name_prefix + } + ###################### + # Instance types variables + ###################### + variable "cpu_core_count" { + description = "CPU core count is used to fetch instance types." + type = number + default = 4 + } + variable "memory_size" { + description = "Memory size used to fetch instance types." + type = number + default = 8 + } + ###################### + # VPC variables + ###################### + variable "vpc_name" { + description = "The vpc name used to create a new vpc when 'vpc_id' is not specified. Default to variable `example_name`" + type = string + default = "tf-k8s-vpc" + } + variable "vpc_cidr" { + description = "The cidr block used to launch a new vpc when 'vpc_id' is not specified." + type = string + default = "10.0.0.0/8" + } + ###################### + # VSwitch variables + ###################### + variable "vswitch_name_prefix" { + type = string + description = "The vswitch name prefix used to create several new vswitches. Default to variable 'example_name'." + default = "tf-k8s-vsw" + } + variable "number_format" { + description = "The number format used to output." + type = string + default = "%02d" + } + variable "vswitch_ids" { + description = "List of existing vswitch id." + type = list + default = [] + } + variable "vswitch_cidrs" { + description = "List of cidr blocks used to create several new vswitches when 'vswitch_ids' is not specified." + type = list + default = [ + "10.1.0.0/16", + "10.2.0.0/16", + "10.3.0.0/16"] + } + variable "k8s_name_prefix" { + description = "The name prefix used to create several kubernetes clusters. Default to variable `example_name`" + type = string + default = "poc" + } + variable "new_nat_gateway" { + type = bool + description = "Whether to create a new nat gateway. In this template, a new nat gateway will create a nat gateway, eip and server snat entries." + default = true + } + variable "master_instance_types" { + description = "The ecs instance types used to launch master nodes." + type = list + default = [ + # hongkong + "ecs.sn1ne.xlarge", + # hongkong + "ecs.c6.xlarge", + # hongkong + "ecs.c4.xlarge", + # hongkong + "ecs.c5.xlarge", + "ecs.n4.xlarge", + # "ecs.n1.large", + # "ecs.sn1.large", + # "ecs.s6-c1m2.xlarge", + # "ecs.c6e.xlarge" + ] + } + variable "worker_instance_types" { + description = "The ecs instance types used to launch worker nodes." + type = list + default = [ + # hongkong + "ecs.sn1ne.xlarge", + # hongkong + "ecs.c6.xlarge", + # hongkong + "ecs.c4.xlarge", + # hongkong + "ecs.c6e.xlarge", + "ecs.n4.xlarge", + // "ecs.n1.large", + // "ecs.sn1.large", + // "ecs.s6-c1m2.xlarge" + ] + } + variable "node_cidr_mask" { + type = number + description = "The node cidr block to specific how many pods can run on single node. Valid values: [24-28]." + default = 24 + } + variable "enable_ssh" { + description = "Enable login to the node through SSH." + type = bool + default = true + } + variable "install_cloud_monitor" { + description = "Install cloud monitor agent on ECS." + type = bool + default = true + } + variable "cpu_policy" { + type = string + description = "kubelet cpu policy. Valid values: 'none','static'. Default to 'none'." + default = "none" + } + variable "proxy_mode" { + description = "Proxy mode is option of kube-proxy. Valid values: 'ipvs','iptables'. Default to 'iptables'." + type = string + default = "iptables" + } + variable "password" { + description = "The password of ECS instance." + type = string + default = "Just4Test" + } + variable "k8s_worker_number" { + description = "The number of worker nodes in kubernetes cluster." + type = number + default = 2 + } + # k8s_pod_cidr is only for flannel network + variable "k8s_pod_cidr" { + description = "The kubernetes pod cidr block. It cannot be equals to vpc's or vswitch's and cannot be in them." + type = string + default = "172.20.0.0/16" + } + variable "k8s_service_cidr" { + description = "The kubernetes service cidr block. It cannot be equals to vpc's or vswitch's or pod's and cannot be in them." + type = string + default = "192.168.0.0/16" + } + variable "k8s_version" { + description = "The version of the kubernetes version. Valid values: '1.16.6-aliyun.1','1.14.8-aliyun.1'. Default to '1.16.6-aliyun.1'." + type = string + default = "1.20.4-aliyun.1" + } + variable "zone_id" { + description = "Availability Zone ID" + type = string + default = "cn-hongkong-b" + # "cn-beijing-a" + } + output "name" { + value = module.kubernetes.name + } + output "kubeconfig" { + value = module.kubernetes.kubeconfig + } + output "cluster_ca_cert" { + value = module.kubernetes.cluster_ca_cert + } + output "client_cert" { + value = module.kubernetes.client_cert + } + output "client_key" { + value = module.kubernetes.client_key + } + output "api_server_internet" { + value = module.kubernetes.api_server_internet + } diff --git a/vela-templates/addons/terraform/definitions/alibaba-oss.yaml b/vela-templates/addons/terraform/definitions/alibaba-oss.yaml new file mode 100644 index 000000000..e84483df9 --- /dev/null +++ b/vela-templates/addons/terraform/definitions/alibaba-oss.yaml @@ -0,0 +1,32 @@ +apiVersion: core.oam.dev/v1alpha2 +kind: ComponentDefinition +metadata: + name: alibaba-oss + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba Cloud OSS object + type: terraform +spec: + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + schematic: + terraform: + configuration: | + resource "alicloud_oss_bucket" "bucket-acl" { + bucket = var.bucket + acl = var.acl + } + output "BUCKET_NAME" { + value = "${alicloud_oss_bucket.bucket-acl.bucket}.${alicloud_oss_bucket.bucket-acl.extranet_endpoint}" + } + variable "bucket" { + description = "OSS bucket name" + default = "vela-website" + type = string + } + variable "acl" { + description = "OSS bucket ACL, supported 'private', 'public-read', 'public-read-write'" + default = "private" + type = string + } \ No newline at end of file diff --git a/vela-templates/addons/terraform/definitions/alibaba-rds.yaml b/vela-templates/addons/terraform/definitions/alibaba-rds.yaml new file mode 100644 index 000000000..adb522489 --- /dev/null +++ b/vela-templates/addons/terraform/definitions/alibaba-rds.yaml @@ -0,0 +1,55 @@ +apiVersion: core.oam.dev/v1alpha2 +kind: ComponentDefinition +metadata: + name: alibaba-rds + annotations: + definition.oam.dev/description: Terraform configuration for Alibaba Cloud RDS object + type: terraform +spec: + workload: + definition: + apiVersion: terraform.core.oam.dev/v1beta1 + kind: Configuration + schematic: + terraform: + configuration: | + module "rds" { + source = "terraform-alicloud-modules/rds/alicloud" + engine = "MySQL" + engine_version = "8.0" + instance_type = "rds.mysql.c1.large" + instance_storage = "20" + instance_name = var.instance_name + account_name = var.account_name + password = var.password + } + output "DB_NAME" { + value = module.rds.this_db_instance_name + } + output "DB_USER" { + value = module.rds.this_db_database_account + } + output "DB_PORT" { + value = module.rds.this_db_instance_port + } + output "DB_HOST" { + value = module.rds.this_db_instance_connection_string + } + output "DB_PASSWORD" { + value = module.rds.this_db_instance_port + } + variable "instance_name" { + description = "RDS instance name" + type = string + default = "poc" + } + variable "account_name" { + description = "RDS instance user account name" + type = string + default = "oam" + } + variable "password" { + description = "RDS instance account password" + type = string + default = "Xyfff83jfewGGfaked" + } \ No newline at end of file