Repository: kubevela/kubevela

Issue:
ComponentRevision Max Number Limit
**Describe the bug**
<!--
A clear and concise description of what the bug is.
-->

Current ComponentRevision do not have a number to limit the max available revision number and automatic garbage collector to recycle outdated ones.

**To Reproduce**
<!--
Steps to reproduce the behavior:
1. The YAML files of Component/Trait I used.
2. The YAML file of Application I applied.
3. Other operations I have done.
4. See error
-->

**Expected behavior**
<!--
A clear and concise description of what you expected to happen.
-->

**Screenshots**
<!--
If applicable, add screenshots to help explain your problem.
-->

**KubeVela Version**

<!--
Describe your KubeVela controller or CLI version information.
-->

**Cluster information**
<!--
Describe your kubernetes cluster information.
- Kubernetes Version [e.g. 1.16.9]
-->

**Additional context**
<!--
Add any other context about the problem here.
-->


Discussion:
@Somefive: If we set ComponentRevisionMaxLimit to 3 and now we have component v1 -> v2 -> v3 -> v4 -> v5.
Then if we edit the component to have the same spec with v3, the v3 revision will be reused. Then we move on to v6. The path is v5 -> v3 -> v6.
The question here is what revisions should v6 keep? If we rely on revision number, (v4, v5, v6) will be kept. On the other hand, if we rely on revision path, (v5, v3, v6) will be kept. @hongchaodeng: Thanks for raising this up... This is a big issue...

> Then if we edit the component to have the same spec with v3, the v3 revision will be reused. Then we move on to v6. The path is v5 -> v3 -> v6.

We probably should rectify the logic to be `v5 -> v6 -> v7`@Somefive: > Thanks for raising this up... This is a big issue...
> 
> > Then if we edit the component to have the same spec with v3, the v3 revision will be reused. Then we move on to v6. The path is v5 -> v3 -> v6.
> 
> We probably should rectify the logic to be `v5 -> v6 -> v7`

So old revision should not be automatically reused except being explicitly specified? @hongchaodeng: Right. From users' perspective, they make a new change. Even though it is equivalent to the previous version, it is a new change and moving forward.

Users could only rollback by specifying explicitly, like what Rollout WorkflowStep does.@briankane: This issue has been inactive for over 2 years and is scheduled for closure as part of our backlog maintenance.

  **If this issue is still relevant:**
  - Please comment below to keep it open
  - Provide updated context if the original description is outdated

  **Timeline:** If there's no activity by **Friday, October 24th**, this issue will be automatically closed.

  **Note:** Issues can always be reopened if they become relevant again. We encourage the community to reopen and reprioritize any incorrectly 
  closed issues.@briankane: This issue has been closed following the stale issue notice. 

If this issue is still relevant and should remain open, please:
1. Reopen the issue
2. Remove the 'stale' label
3. Provide an update on the current status or importance

Thank you for your understanding and contribution to KubeVela!

Solution patch:
diff --git a/README.md b/README.md
index 82d58655..21934d0d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,11 @@
+<div style="text-align: center">
+  <p align="center">
+    <img src="https://raw.githubusercontent.com/oam-dev/kubevela.io/main/docs/resources/KubeVela-03.png">
+    <br><br>
+    <i>Make shipping applications more enjoyable.</i>
+  </p>
+</div>
+
 ![Build status](https://github.com/oam-dev/kubevela/workflows/E2E/badge.svg)
 [![Go Report Card](https://goreportcard.com/badge/github.com/oam-dev/kubevela)](https://goreportcard.com/report/github.com/oam-dev/kubevela)
 ![Docker Pulls](https://img.shields.io/docker/pulls/oamdev/vela-core)
@@ -8,23 +16,21 @@
 [![Twitter](https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Ftwitter.com%2Foam_dev)](https://twitter.com/oam_dev)
 [![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/kubevela)](https://artifacthub.io/packages/search?repo=kubevela)
 
-![logo](https://raw.githubusercontent.com/oam-dev/kubevela.io/main/docs/resources/KubeVela-03.png)
-
-*Make shipping applications more enjoyable.*
+## Introduction
 
-# KubeVela
+KubeVela is a modern application delivery platform that makes deploying and operating applications across today's hybrid, multi-cloud environments easier, faster and more reliable.
 
-KubeVela is a modern application platform that makes deploying and managing applications across today's hybrid, multi-cloud environments easier and faster.
+![](docs/resources/what-is-kubevela.png)
 
-![](docs/resources/arch.png)
+## Highlights
 
-## Features
+KubeVela practices the "render, orchestrate, deploy" workflow with below highlighted values added to existing ecosystem:
 
-**Application Centric** - KubeVela introduces [Open Application Model (OAM)](https://oam.dev/) as the consistent yet higher level API to capture a full deployment of microservices on top of hybrid environments. Placement strategy, traffic shifting and rolling update are declared at application level. No infrastructure level concern, simply deploy.
+- *Application Centric* - KubeVela introduces [Open Application Model (OAM)](https://oam.dev/) as the consistent yet higher level API to capture and render a full deployment of microservices on top of hybrid environments. Placement strategy, traffic shifting and rolling update are declared at application level. No infrastructure level concern, simply deploy.
 
-**Programmable Workflow** - KubeVela models application delivery as DAG (Directed Acyclic Graph) and expresses it with [CUE](https://cuelang.org/), a modern data configuration language. This allows you to declare application deployment workflow with all steps and delivery needs assembled together in programmable approach. No restrictions, natively extensible.
+- *Programmable Workflow* - KubeVela models application delivery as DAG (Directed Acyclic Graph) and expresses it with [CUE](https://cuelang.org/) - a modern data configuration language. This allows you to design application deployment steps per needs and orchestrate them in programmable approach. No restrictions, natively extensible.
 
-**Infrastructure Agnostic** - KubeVela works as an application delivery control plane that is fully decoupled from runtime infrastructure. Hence it can deploy and manage any application types including containers, cloud services, databases, or even EC2 instances across hybrid environments, following the workflow you designed.
+- *Infrastructure Agnostic* - KubeVela works as an application delivery control plane that is fully decoupled from runtime infrastructure. It can deploy any workload types including containers, cloud services, databases, or even VM instances to any cloud or Kubernetes cluster, following the workflow designed by you.
 
 ## Getting Started
 
diff --git a/apis/core.oam.dev/common/types.go b/apis/core.oam.dev/common/types.go
index 0ce70d4a..d7f7abc0 100644
--- a/apis/core.oam.dev/common/types.go
+++ b/apis/core.oam.dev/common/types.go
@@ -20,6 +20,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 
+	types "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
+
 	"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
 
 	"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
@@ -109,6 +111,9 @@ type Terraform struct {
 	// +kubebuilder:default:=hcl
 	// +kubebuilder:validation:Enum:=hcl;json;remote
 	Type string `json:"type,omitempty"`
+
+	// ProviderReference specifies the reference to Provider
+	ProviderReference *types.Reference `json:"providerRef,omitempty"`
 }
 
 // A WorkloadTypeDescriptor refer to a Workload Type
diff --git a/apis/core.oam.dev/common/zz_generated.deepcopy.go b/apis/core.oam.dev/common/zz_generated.deepcopy.go
index 9d32b6e1..87e302fd 100644
--- a/apis/core.oam.dev/common/zz_generated.deepcopy.go
+++ b/apis/core.oam.dev/common/zz_generated.deepcopy.go
@@ -21,6 +21,7 @@ limitations under the License.
 package common
 
 import (
+	crossplane_runtime "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
 	v1 "k8s.io/api/core/v1"
 )
 
@@ -443,7 +444,7 @@ func (in *Schematic) DeepCopyInto(out *Schematic) {
 	if in.Terraform != nil {
 		in, out := &in.Terraform, &out.Terraform
 		*out = new(Terraform)
-		**out = **in
+		(*in).DeepCopyInto(*out)
 	}
 }
 
@@ -533,6 +534,11 @@ func (in *SubStepsStatus) DeepCopy() *SubStepsStatus {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Terraform) DeepCopyInto(out *Terraform) {
 	*out = *in
+	if in.ProviderReference != nil {
+		in, out := &in.ProviderReference, &out.ProviderReference
+		*out = new(crossplane_runtime.Reference)
+		**out = **in
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Terraform.
diff --git a/apis/types/types.go b/apis/types/types.go
index 09d18191..0680be14 100644
--- a/apis/types/types.go
+++ b/apis/types/types.go
@@ -47,12 +47,13 @@ const (
 	StatusStaging = "Staging"
 )
 
-// EnvMeta stores the info for app environment
+// Config contains key/value pairs
+type Config map[string]string
+
+// EnvMeta stores the namespace for app environment
 type EnvMeta struct {
 	Name      string `json:"name"`
 	Namespace string `json:"namespace"`
-	Email     string `json:"email,omitempty"`
-	Domain    string `json:"domain,omitempty"`
 
 	Current string `json:"current,omitempty"`
 }
diff --git a/charts/oam-runtime/crds/core.oam.dev_traitdefinitions.yaml b/charts/oam-runtime/crds/core.oam.dev_traitdefinitions.yaml
index bc30ce8e..6d694258 100644
--- a/charts/oam-runtime/crds/core.oam.dev_traitdefinitions.yaml
+++ b/charts/oam-runtime/crds/core.oam.dev_traitdefinitions.yaml
@@ -188,6 +188,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -454,6 +468,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/oam-runtime/crds/core.oam.dev_workloaddefinitions.yaml b/charts/oam-runtime/crds/core.oam.dev_workloaddefinitions.yaml
index 26487a53..80d37924 100644
--- a/charts/oam-runtime/crds/core.oam.dev_workloaddefinitions.yaml
+++ b/charts/oam-runtime/crds/core.oam.dev_workloaddefinitions.yaml
@@ -193,6 +193,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -440,6 +454,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/crds/core.oam.dev_applicationrevisions.yaml b/charts/vela-core/crds/core.oam.dev_applicationrevisions.yaml
index 9a1193c0..306b2ace 100644
--- a/charts/vela-core/crds/core.oam.dev_applicationrevisions.yaml
+++ b/charts/vela-core/crds/core.oam.dev_applicationrevisions.yaml
@@ -1232,6 +1232,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -1621,6 +1635,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -1908,6 +1936,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3318,6 +3360,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3600,6 +3656,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3971,6 +4041,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -4221,6 +4305,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -4487,6 +4585,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/crds/core.oam.dev_componentdefinitions.yaml b/charts/vela-core/crds/core.oam.dev_componentdefinitions.yaml
index d10e8e6a..10530b94 100644
--- a/charts/vela-core/crds/core.oam.dev_componentdefinitions.yaml
+++ b/charts/vela-core/crds/core.oam.dev_componentdefinitions.yaml
@@ -179,6 +179,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -449,6 +463,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/crds/core.oam.dev_definitionrevisions.yaml b/charts/vela-core/crds/core.oam.dev_definitionrevisions.yaml
index 150b5df8..4e81135c 100644
--- a/charts/vela-core/crds/core.oam.dev_definitionrevisions.yaml
+++ b/charts/vela-core/crds/core.oam.dev_definitionrevisions.yaml
@@ -222,6 +222,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -492,6 +506,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -755,6 +783,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -999,6 +1041,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/crds/core.oam.dev_policydefinitions.yaml b/charts/vela-core/crds/core.oam.dev_policydefinitions.yaml
index b37983de..07169c70 100644
--- a/charts/vela-core/crds/core.oam.dev_policydefinitions.yaml
+++ b/charts/vela-core/crds/core.oam.dev_policydefinitions.yaml
@@ -151,6 +151,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/crds/core.oam.dev_traitdefinitions.yaml b/charts/vela-core/crds/core.oam.dev_traitdefinitions.yaml
index bc30ce8e..6d694258 100644
--- a/charts/vela-core/crds/core.oam.dev_traitdefinitions.yaml
+++ b/charts/vela-core/crds/core.oam.dev_traitdefinitions.yaml
@@ -188,6 +188,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -454,6 +468,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/crds/core.oam.dev_workflowstepdefinitions.yaml b/charts/vela-core/crds/core.oam.dev_workflowstepdefinitions.yaml
index 9b9464f2..025dee2f 100644
--- a/charts/vela-core/crds/core.oam.dev_workflowstepdefinitions.yaml
+++ b/charts/vela-core/crds/core.oam.dev_workflowstepdefinitions.yaml
@@ -148,6 +148,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/crds/core.oam.dev_workloaddefinitions.yaml b/charts/vela-core/crds/core.oam.dev_workloaddefinitions.yaml
index 26487a53..80d37924 100644
--- a/charts/vela-core/crds/core.oam.dev_workloaddefinitions.yaml
+++ b/charts/vela-core/crds/core.oam.dev_workloaddefinitions.yaml
@@ -193,6 +193,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -440,6 +454,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-core/templates/addons/terraform-provider-azure.yaml b/charts/vela-core/templates/addons/terraform-provider-azure.yaml
new file mode 100644
index 00000000..df5515e3
--- /dev/null
+++ b/charts/vela-core/templates/addons/terraform-provider-azure.yaml
@@ -0,0 +1,58 @@
+apiVersion: v1
+data:
+  initializer: |
+    apiVersion: core.oam.dev/v1beta1
+    kind: Initializer
+    metadata:
+      annotations:
+        addons.oam.dev/description: Kubernetes Terraform Controller for Azure
+        addons.oam.dev/name: terraform/provider-azure
+      name: terraform-provider-azure
+      namespace: default
+    spec:
+      appTemplate:
+        spec:
+          components:
+          - name: azure-account-creds
+            properties:
+              apiVersion: v1
+              kind: Secret
+              metadata:
+                name: azure-account-creds
+                namespace: vela-system
+              stringData:
+                credentials: |
+                  armClientID: [[ index .Args "ARM_CLIENT_ID" ]]
+                  armClientSecret: [[ index .Args "ARM_CLIENT_SECRET" ]]
+                  armSubscriptionID: [[ index .Args "ARM_SUBSCRIPTION_ID" ]]
+                  armTenantID: [[ index .Args "ARM_TENANT_ID" ]]
+              type: Opaque
+            type: raw
+          - name: azure
+            properties:
+              apiVersion: terraform.core.oam.dev/v1beta1
+              kind: Provider
+              metadata:
+                name: azure
+                namespace: default
+              spec:
+                credentials:
+                  secretRef:
+                    key: credentials
+                    name: azure-account-creds
+                    namespace: vela-system
+                  source: Secret
+                provider: azure
+            type: raw
+        status: {}
+    status:
+      observedGeneration: 0
+kind: ConfigMap
+metadata:
+  annotations:
+    addons.oam.dev/description: Kubernetes Terraform Controller for Azure
+    addons.oam.dev/name: terraform/provider-azure
+  labels:
+    addons.oam.dev/type: terraform-provider-azure
+  name: terraform-provider-azure
+  namespace: {{.Values.systemDefinitionNamespace}}
diff --git a/charts/vela-core/templates/addons/terraform.yaml b/charts/vela-core/templates/addons/terraform.yaml
index 30eecd88..5450ba3e 100644
--- a/charts/vela-core/templates/addons/terraform.yaml
+++ b/charts/vela-core/templates/addons/terraform.yaml
@@ -354,6 +354,83 @@ data:
                     apiVersion: terraform.core.oam.dev/v1beta1
                     kind: Configuration
             type: raw
+          - name: azure-database-mariadb
+            properties:
+              apiVersion: core.oam.dev/v1alpha2
+              kind: ComponentDefinition
+              metadata:
+                annotations:
+                  definition.oam.dev/description: Terraform configuration for Azure Database
+                    Mariadb
+                  provider: azure
+                labels:
+                  type: terraform
+                name: azure-database-mariadb
+                namespace: vela-system
+              spec:
+                schematic:
+                  terraform:
+                    configuration: |
+                      # Configure the Microsoft Azure Provider
+                      provider "azurerm" {
+                        features {}
+                      }
+
+                      resource "azurerm_resource_group" "example" {
+                        name = "tfex-mariadb-database-RG"
+                        location = "West Europe"
+                      }
+
+                      resource "azurerm_mariadb_server" "example" {
+                        name = "mariadb-svr-sample"
+                        location = azurerm_resource_group.example.location
+                        resource_group_name = azurerm_resource_group.example.name
+
+                        sku_name = "B_Gen5_2"
+
+                        storage_mb = 51200
+                        backup_retention_days = 7
+                        geo_redundant_backup_enabled = false
+
+                        administrator_login = var.username
+                        administrator_login_password = var.password
+                        version = "10.2"
+                        ssl_enforcement_enabled = true
+                      }
+
+                      resource "azurerm_mariadb_database" "example" {
+                        name = var.name
+                        resource_group_name = azurerm_resource_group.example.name
+                        server_name = azurerm_mariadb_server.example.name
+                        charset = "utf8"
+                        collation = "utf8_general_ci"
+                      }
+
+                      variable "name" {
+                        default = "mariadb_database"
+                        type = string
+                        description = "Database instance name"
+                      }
+
+                      variable "username" {
+                        default = "acctestun"
+                        type = string
+                        description = "Database instance username"
+                      }
+
+                      variable "password" {
+                        default = "H@Sh1CoR3!faked"
+                        type = string
+                        description = "Database instance password"
+                      }
+                    providerRef:
+                      name: azure
+                      namespace: default
+                workload:
+                  definition:
+                    apiVersion: terraform.core.oam.dev/v1beta1
+                    kind: Configuration
+            type: raw
         status: {}
       dependsOn:
       - ref:
diff --git a/charts/vela-minimal/crds/core.oam.dev_applicationrevisions.yaml b/charts/vela-minimal/crds/core.oam.dev_applicationrevisions.yaml
index 9a1193c0..306b2ace 100644
--- a/charts/vela-minimal/crds/core.oam.dev_applicationrevisions.yaml
+++ b/charts/vela-minimal/crds/core.oam.dev_applicationrevisions.yaml
@@ -1232,6 +1232,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -1621,6 +1635,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -1908,6 +1936,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3318,6 +3360,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3600,6 +3656,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3971,6 +4041,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -4221,6 +4305,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -4487,6 +4585,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
diff --git a/charts/vela-minimal/crds/core.oam.dev_definitionrevisions.yaml b/charts/vela-minimal/crds/core.oam.dev_definitionrevisions.yaml
index 150b5df8..4e81135c 100644
--- a/charts/vela-minimal/crds/core.oam.dev_definitionrevisions.yaml
+++ b/charts/vela-minimal/crds/core.oam.dev_definitionrevisions.yaml
@@ -222,6 +222,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -492,6 +506,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -755,6 +783,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -999,6 +1041,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
diff --git a/charts/vela-minimal/crds/core.oam.dev_policydefinitions.yaml b/charts/vela-minimal/crds/core.oam.dev_policydefinitions.yaml
index b37983de..07169c70 100644
--- a/charts/vela-minimal/crds/core.oam.dev_policydefinitions.yaml
+++ b/charts/vela-minimal/crds/core.oam.dev_policydefinitions.yaml
@@ -151,6 +151,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-minimal/crds/core.oam.dev_traitdefinitions.yaml b/charts/vela-minimal/crds/core.oam.dev_traitdefinitions.yaml
index bc30ce8e..6d694258 100644
--- a/charts/vela-minimal/crds/core.oam.dev_traitdefinitions.yaml
+++ b/charts/vela-minimal/crds/core.oam.dev_traitdefinitions.yaml
@@ -188,6 +188,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -454,6 +468,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-minimal/crds/core.oam.dev_workflowstepdefinitions.yaml b/charts/vela-minimal/crds/core.oam.dev_workflowstepdefinitions.yaml
index 9b9464f2..025dee2f 100644
--- a/charts/vela-minimal/crds/core.oam.dev_workflowstepdefinitions.yaml
+++ b/charts/vela-minimal/crds/core.oam.dev_workflowstepdefinitions.yaml
@@ -148,6 +148,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/charts/vela-minimal/crds/core.oam.dev_workloaddefinitions.yaml b/charts/vela-minimal/crds/core.oam.dev_workloaddefinitions.yaml
index 26487a53..80d37924 100644
--- a/charts/vela-minimal/crds/core.oam.dev_workloaddefinitions.yaml
+++ b/charts/vela-minimal/crds/core.oam.dev_workloaddefinitions.yaml
@@ -193,6 +193,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -440,6 +454,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/cmd/core/main.go b/cmd/core/main.go
index b21b2b81..871a0e11 100644
--- a/cmd/core/main.go
+++ b/cmd/core/main.go
@@ -30,6 +30,7 @@ import (
 	"strings"
 	"time"
 
+	appsv1 "k8s.io/api/apps/v1"
 	"k8s.io/klog/v2"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -206,7 +207,7 @@ func main() {
 		LeaseDuration:              &leaseDuration,
 		RenewDeadline:              &renewDeadline,
 		RetryPeriod:                &retryPeriod,
-		ClientDisableCacheFor:      []client.Object{&v1beta1.ResourceTracker{}},
+		ClientDisableCacheFor:      []client.Object{&v1beta1.ResourceTracker{}, &appsv1.ControllerRevision{}},
 	})
 	if err != nil {
 		klog.ErrorS(err, "Unable to create a controller manager")
diff --git a/docs/resources/arch.png b/docs/resources/arch.png
deleted file mode 100644
index 4b7529eb..00000000
Binary files a/docs/resources/arch.png and /dev/null differ
diff --git a/docs/resources/what-is-kubevela.png b/docs/resources/what-is-kubevela.png
new file mode 100644
index 00000000..0a5f8e02
Binary files /dev/null and b/docs/resources/what-is-kubevela.png differ
diff --git a/e2e/commonContext.go b/e2e/commonContext.go
index 5b5e4937..b64d94e3 100644
--- a/e2e/commonContext.go
+++ b/e2e/commonContext.go
@@ -33,7 +33,7 @@ var (
 				cli := fmt.Sprintf("vela env init %s", envName)
 				output, err := Exec(cli)
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
-				expectedOutput := fmt.Sprintf("environment %s created,", envName)
+				expectedOutput := fmt.Sprintf("environment %s created", envName)
 				gomega.Expect(output).To(gomega.ContainSubstring(expectedOutput))
 			})
 		})
@@ -45,7 +45,7 @@ var (
 				cli := fmt.Sprintf("vela env init %s --namespace %s", envName, namespace)
 				output, err := Exec(cli)
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
-				expectedOutput := fmt.Sprintf("environment %s created,", envName)
+				expectedOutput := fmt.Sprintf("environment %s created", envName)
 				gomega.Expect(output).To(gomega.ContainSubstring(expectedOutput))
 			})
 		})
diff --git a/go.mod b/go.mod
index dd731bc3..7f71d8de 100644
--- a/go.mod
+++ b/go.mod
@@ -34,7 +34,7 @@ require (
 	github.com/mitchellh/hashstructure/v2 v2.0.1
 	github.com/oam-dev/cluster-gateway v0.0.0-20210907072424-2f8720b116f8
 	github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28
-	github.com/oam-dev/terraform-controller v0.2.0
+	github.com/oam-dev/terraform-controller v0.2.1
 	github.com/olekukonko/tablewriter v0.0.5
 	github.com/onsi/ginkgo v1.16.4
 	github.com/onsi/gomega v1.16.0
diff --git a/go.sum b/go.sum
index 58bdfcab..a4f2aee8 100644
--- a/go.sum
+++ b/go.sum
@@ -1207,8 +1207,8 @@ github.com/oam-dev/stern v1.13.0-alpha h1:EVjM8Qvh6LssB6t4RZrjf9DtCq1cz+/cy6OF7f
 github.com/oam-dev/stern v1.13.0-alpha/go.mod h1:AOkvfFUv0Arz7GBi0jz7S0Jsu4K/kdvSjNsnRt1+BIg=
 github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28 h1:tD8HiFKnt0jnwdTWjeqUnfnUYLD/+Nsmj8ZGIxqDWiU=
 github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28/go.mod h1:Mu8i0/DdplvnjwRbAYPsc8+LRR27n/mp8VWdkN10GzE=
-github.com/oam-dev/terraform-controller v0.2.0 h1:GBQ+CvXtY9bcRkwGaPYHbYFkbVWzDExc05hz0NL0rqs=
-github.com/oam-dev/terraform-controller v0.2.0/go.mod h1:wd4rnqnJzz274Sg1/qoeIhBx1rvTZ/ECzXoMff0ucR0=
+github.com/oam-dev/terraform-controller v0.2.1 h1:gGXcUDBMWKfWet84STm99RX6gXo89pyTRsgQSLq2mog=
+github.com/oam-dev/terraform-controller v0.2.1/go.mod h1:5Vy6jLx9fjotEd6E005Ve1f0x3fEpVlG/DVjmqLjAq0=
 github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
 github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
 github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
diff --git a/legacy/charts/vela-core-legacy/crds/core.oam.dev_applicationrevisions.yaml b/legacy/charts/vela-core-legacy/crds/core.oam.dev_applicationrevisions.yaml
index fd2b5be2..5813fd71 100644
--- a/legacy/charts/vela-core-legacy/crds/core.oam.dev_applicationrevisions.yaml
+++ b/legacy/charts/vela-core-legacy/crds/core.oam.dev_applicationrevisions.yaml
@@ -1232,6 +1232,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -1621,6 +1635,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -1908,6 +1936,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3318,6 +3360,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3600,6 +3656,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -3971,6 +4041,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -4221,6 +4305,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
@@ -4487,6 +4585,20 @@ spec:
                                 configuration:
                                   description: Configuration is Terraform Configuration
                                   type: string
+                                providerRef:
+                                  description: ProviderReference specifies the reference
+                                    to Provider
+                                  properties:
+                                    name:
+                                      description: Name of the referenced object.
+                                      type: string
+                                    namespace:
+                                      default: default
+                                      description: Namespace of the secret.
+                                      type: string
+                                  required:
+                                  - name
+                                  type: object
                                 type:
                                   default: hcl
                                   description: Type specifies which Terraform configuration
diff --git a/legacy/charts/vela-core-legacy/crds/core.oam.dev_componentdefinitions.yaml b/legacy/charts/vela-core-legacy/crds/core.oam.dev_componentdefinitions.yaml
index 38b02444..a29c120d 100644
--- a/legacy/charts/vela-core-legacy/crds/core.oam.dev_componentdefinitions.yaml
+++ b/legacy/charts/vela-core-legacy/crds/core.oam.dev_componentdefinitions.yaml
@@ -179,6 +179,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -449,6 +463,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/legacy/charts/vela-core-legacy/crds/core.oam.dev_definitionrevisions.yaml b/legacy/charts/vela-core-legacy/crds/core.oam.dev_definitionrevisions.yaml
index e1e0d870..a58389fd 100644
--- a/legacy/charts/vela-core-legacy/crds/core.oam.dev_definitionrevisions.yaml
+++ b/legacy/charts/vela-core-legacy/crds/core.oam.dev_definitionrevisions.yaml
@@ -222,6 +222,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -492,6 +506,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -755,6 +783,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
@@ -999,6 +1041,20 @@ spec:
                               configuration:
                                 description: Configuration is Terraform Configuration
                                 type: string
+                              providerRef:
+                                description: ProviderReference specifies the reference
+                                  to Provider
+                                properties:
+                                  name:
+                                    description: Name of the referenced object.
+                                    type: string
+                                  namespace:
+                                    default: default
+                                    description: Namespace of the secret.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               type:
                                 default: hcl
                                 description: Type specifies which Terraform configuration
diff --git a/legacy/charts/vela-core-legacy/crds/core.oam.dev_policydefinitions.yaml b/legacy/charts/vela-core-legacy/crds/core.oam.dev_policydefinitions.yaml
index 84c93c8c..8f71e4c5 100644
--- a/legacy/charts/vela-core-legacy/crds/core.oam.dev_policydefinitions.yaml
+++ b/legacy/charts/vela-core-legacy/crds/core.oam.dev_policydefinitions.yaml
@@ -151,6 +151,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/legacy/charts/vela-core-legacy/crds/core.oam.dev_traitdefinitions.yaml b/legacy/charts/vela-core-legacy/crds/core.oam.dev_traitdefinitions.yaml
index 2e6ae3bf..5cce855a 100644
--- a/legacy/charts/vela-core-legacy/crds/core.oam.dev_traitdefinitions.yaml
+++ b/legacy/charts/vela-core-legacy/crds/core.oam.dev_traitdefinitions.yaml
@@ -188,6 +188,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -454,6 +468,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/legacy/charts/vela-core-legacy/crds/core.oam.dev_workflowstepdefinitions.yaml b/legacy/charts/vela-core-legacy/crds/core.oam.dev_workflowstepdefinitions.yaml
index 7313a130..91c8228f 100644
--- a/legacy/charts/vela-core-legacy/crds/core.oam.dev_workflowstepdefinitions.yaml
+++ b/legacy/charts/vela-core-legacy/crds/core.oam.dev_workflowstepdefinitions.yaml
@@ -148,6 +148,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/legacy/charts/vela-core-legacy/crds/core.oam.dev_workloaddefinitions.yaml b/legacy/charts/vela-core-legacy/crds/core.oam.dev_workloaddefinitions.yaml
index 3e1a61b6..419a9e8f 100644
--- a/legacy/charts/vela-core-legacy/crds/core.oam.dev_workloaddefinitions.yaml
+++ b/legacy/charts/vela-core-legacy/crds/core.oam.dev_workloaddefinitions.yaml
@@ -193,6 +193,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
@@ -440,6 +454,20 @@ spec:
                       configuration:
                         description: Configuration is Terraform Configuration
                         type: string
+                      providerRef:
+                        description: ProviderReference specifies the reference to
+                          Provider
+                        properties:
+                          name:
+                            description: Name of the referenced object.
+                            type: string
+                          namespace:
+                            default: default
+                            description: Namespace of the secret.
+                            type: string
+                        required:
+                        - name
+                        type: object
                       type:
                         default: hcl
                         description: Type specifies which Terraform configuration
diff --git a/pkg/appfile/appfile.go b/pkg/appfile/appfile.go
index c05b61ab..8ec7aacb 100644
--- a/pkg/appfile/appfile.go
+++ b/pkg/appfile/appfile.go
@@ -649,7 +649,7 @@ func generateComponentFromKubeModule(wl *Workload, appName, revision, ns string)
 }
 
 func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructured.Unstructured, error) {
-	if wl.FullTemplate.Terraform.Configuration == "" {
+	if wl.FullTemplate == nil || wl.FullTemplate.Terraform == nil || wl.FullTemplate.Terraform.Configuration == "" {
 		return nil, errors.New(errTerraformConfigurationIsNotSet)
 	}
 	params, err := json.Marshal(wl.Params)
@@ -671,6 +671,10 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
 		configuration.Spec.Remote = wl.FullTemplate.Terraform.Configuration
 	}
 
+	if wl.FullTemplate.Terraform.ProviderReference != nil {
+		configuration.Spec.ProviderReference = wl.FullTemplate.Terraform.ProviderReference
+	}
+
 	// 1. parse writeConnectionSecretToRef
 	if err := json.Unmarshal(params, &configuration.Spec); err != nil {
 		return nil, errors.Wrap(err, errFailToConvertTerraformComponentProperties)
diff --git a/pkg/appfile/config/configmap.go b/pkg/appfile/config/configmap.go
deleted file mode 100644
index 2c3260fb..00000000
--- a/pkg/appfile/config/configmap.go
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package config
-
-import (
-	"context"
-	"strings"
-
-	v1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-const (
-	// Splitter is a splitter for configmap name generation
-	Splitter = "-"
-
-	// TypeConfigMap defines the type of Configmap
-	TypeConfigMap = "configmap"
-)
-
-// ToConfigMap will get the data of the store and upload to configmap.
-// Serverside Application controller can only use the config in appfile context by configmap.
-func ToConfigMap(s Store, name, envName string, configData map[string]string) (*v1.ConfigMap, error) {
-	namespace, err := s.Namespace(envName)
-	if err != nil {
-		return nil, err
-	}
-	var cm = v1.ConfigMap{
-		TypeMeta: metav1.TypeMeta{
-			APIVersion: "v1",
-			Kind:       "ConfigMap",
-		},
-	}
-	cm.SetName(name)
-	cm.SetNamespace(namespace)
-	cm.Data = configData
-	return &cm, nil
-}
-
-// GenConfigMapName is a fixed way to name the configmap name for appfile config
-func GenConfigMapName(appName, serviceName, configName string) string {
-	return strings.Join([]string{"kubevela", appName, serviceName, configName}, Splitter)
-}
-
-var _ Store = &Configmap{}
-
-// Configmap is the configmap implementation of config store
-type Configmap struct {
-	Client client.Client
-}
-
-// GetConfigData will get config data from configmap
-func (f *Configmap) GetConfigData(name, envName string) ([]map[string]string, error) {
-
-	namespace, err := f.Namespace(envName)
-	if err != nil {
-		return nil, err
-	}
-
-	var cm v1.ConfigMap
-	err = f.Client.Get(context.Background(), client.ObjectKey{Name: name, Namespace: namespace}, &cm)
-	if err != nil {
-		return nil, err
-	}
-	var data []map[string]string
-	for k, v := range cm.Data {
-		data = append(data, EncodeConfigFormat(k, v))
-	}
-	return data, nil
-}
-
-// Namespace returns the namespace of the config store from env
-func (f *Configmap) Namespace(envName string) (string, error) {
-	// TODO(wonderflow): now we regard env as namespace, it should be fixed when env is store serverside as configmap
-	return envName, nil
-}
-
-// Type returns the type of the config store
-func (Configmap) Type() string {
-	return TypeConfigMap
-}
diff --git a/pkg/appfile/config/local.go b/pkg/appfile/config/local.go
deleted file mode 100644
index c0042c7b..00000000
--- a/pkg/appfile/config/local.go
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package config
-
-import (
-	"bufio"
-	"bytes"
-
-	"github.com/oam-dev/kubevela/pkg/utils/config"
-	env2 "github.com/oam-dev/kubevela/pkg/utils/env"
-)
-
-// TypeLocal defines the local config store type
-const TypeLocal = "local"
-
-// Local is the local implementation of config store
-type Local struct{}
-
-var _ Store = &Local{}
-
-// GetConfigData will return config data from local
-func (l *Local) GetConfigData(configName, envName string) ([]map[string]string, error) {
-	cfgData, err := config.ReadConfig(envName, configName)
-	if err != nil {
-		return nil, err
-	}
-	scanner := bufio.NewScanner(bytes.NewReader(cfgData))
-	var data []map[string]string
-	for scanner.Scan() {
-		k, v, err := config.ReadConfigLine(scanner.Text())
-		if err != nil {
-			return nil, err
-		}
-		data = append(data, EncodeConfigFormat(k, v))
-	}
-	return data, nil
-}
-
-// Namespace return namespace from env
-func (l *Local) Namespace(envName string) (string, error) {
-	env, err := env2.GetEnvByName(envName)
-	if err != nil {
-		return "", err
-	}
-	return env.Namespace, nil
-}
-
-// Type returns the type of this config store implementation
-func (l *Local) Type() string {
-	return TypeLocal
-}
diff --git a/pkg/appfile/config/store.go b/pkg/appfile/config/store.go
deleted file mode 100644
index 7a656917..00000000
--- a/pkg/appfile/config/store.go
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package config
-
-import "errors"
-
-// Store will get config data
-type Store interface {
-	GetConfigData(configName, envName string) ([]map[string]string, error)
-	Type() string
-	Namespace(envName string) (string, error)
-}
-
-// TypeFake is a fake type
-const TypeFake = "fake"
-
-var _ Store = &Fake{}
-
-// Fake is a fake implementation of config store, help for test
-type Fake struct {
-	Data []map[string]string
-}
-
-// GetConfigData get data
-func (f *Fake) GetConfigData(_ string, _ string) ([]map[string]string, error) {
-	return f.Data, nil
-}
-
-// Type return the type
-func (Fake) Type() string {
-	return TypeFake
-}
-
-// Namespace return the Namespace
-func (Fake) Namespace(_ string) (string, error) {
-	return "", nil
-}
-
-// EncodeConfigFormat will encode key-value to config{name: key, value: value} format
-func EncodeConfigFormat(key, value string) map[string]string {
-	return map[string]string{
-		"name":  key,
-		"value": value,
-	}
-}
-
-// DecodeConfigFormat will decode config{name: key, value: value} format to key-value mode.
-func DecodeConfigFormat(data []map[string]string) (map[string]string, error) {
-	var res = make(map[string]string)
-	for _, d := range data {
-		key, ok := d["name"]
-		if !ok {
-			return nil, errors.New("invalid data format, no 'name' found")
-		}
-		value, ok := d["value"]
-		if !ok {
-			return nil, errors.New("invalid data format, no 'value' found")
-		}
-		res[key] = value
-	}
-	return res, nil
-}
diff --git a/pkg/controller/core.oam.dev/v1alpha1/envbinding/cluster_gateway_engine.go b/pkg/controller/core.oam.dev/v1alpha1/envbinding/cluster_gateway_engine.go
index b361f042..d275a720 100644
--- a/pkg/controller/core.oam.dev/v1alpha1/envbinding/cluster_gateway_engine.go
+++ b/pkg/controller/core.oam.dev/v1alpha1/envbinding/cluster_gateway_engine.go
@@ -22,6 +22,7 @@ import (
 	"github.com/pkg/errors"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -79,30 +80,20 @@ func (engine *ClusterGatewayEngine) prepare(ctx context.Context, configs []v1alp
 }
 
 func (engine *ClusterGatewayEngine) initEnvBindApps(ctx context.Context, envBinding *v1alpha1.EnvBinding, baseApp *v1beta1.Application, appParser *appfile.Parser) ([]*EnvBindApp, error) {
-	envBindApps, err := CreateEnvBindApps(envBinding, baseApp)
-	if err != nil {
-		return nil, err
-	}
-	if err = RenderEnvBindApps(ctx, envBindApps, appParser); err != nil {
-		return nil, err
-	}
-	if err = AssembleEnvBindApps(envBindApps); err != nil {
-		return nil, err
-	}
-	return envBindApps, nil
+	return CreateEnvBindApps(envBinding, baseApp)
 }
 
 func (engine *ClusterGatewayEngine) schedule(ctx context.Context, apps []*EnvBindApp) ([]v1alpha1.ClusterDecision, error) {
 	for _, app := range apps {
 		app.ScheduledManifests = make(map[string]*unstructured.Unstructured)
 		clusterName := engine.clusterDecisions[app.envConfig.Name].Cluster
-		for _, component := range app.PatchedApp.Spec.Components {
-			for _, manifest := range app.assembledManifests[component.Name] {
-				manifestName := component.Name + "/" + manifest.GetName()
-				multicluster.SetClusterName(manifest, clusterName)
-				app.ScheduledManifests[manifestName] = manifest
-			}
+		raw, err := runtime.DefaultUnstructuredConverter.ToUnstructured(app.PatchedApp)
+		if err != nil {
+			return nil, errors.Wrapf(err, "failed to convert app [Env: %s](%s/%s) into unstructured", app.envConfig.Name, app.PatchedApp.Namespace, app.PatchedApp.Name)
 		}
+		patchedApp := &unstructured.Unstructured{Object: raw}
+		multicluster.SetClusterName(patchedApp, clusterName)
+		app.ScheduledManifests[patchedApp.GetName()] = patchedApp
 	}
 	var decisions []v1alpha1.ClusterDecision
 	for _, decision := range engine.clusterDecisions {
diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/dispatch/dispatch.go b/pkg/controller/core.oam.dev/v1alpha2/application/dispatch/dispatch.go
index 474af7c6..aeb13bc1 100644
--- a/pkg/controller/core.oam.dev/v1alpha2/application/dispatch/dispatch.go
+++ b/pkg/controller/core.oam.dev/v1alpha2/application/dispatch/dispatch.go
@@ -199,7 +199,7 @@ func (a *AppManifestsDispatcher) retrieveLegacyResourceTrackers(ctx context.Cont
 	}
 	for _, rt := range rtList.Items {
 		if rt.Name != a.currentRTName &&
-			(a.previousRT != nil && rt.Name != a.previousRT.Name) {
+			(a.previousRT != nil && rt.Name != a.previousRT.Name) && !IsLifeLongResourceTracker(rt) {
 			a.legacyRTs = append(a.legacyRTs, rt.DeepCopy())
 		}
 	}
@@ -357,3 +357,9 @@ func setOrOverrideOAMControllerOwner(obj ObjectOwner, controllerOwner metav1.Own
 	}
 	obj.SetOwnerReferences(newOwnerRefs)
 }
+
+// IsLifeLongResourceTracker check if resourcetracker shares the same whole life with the entire application
+func IsLifeLongResourceTracker(rt v1beta1.ResourceTracker) bool {
+	_, ok := rt.GetAnnotations()[oam.AnnotationResourceTrackerLifeLong]
+	return ok
+}
diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/generator.go b/pkg/controller/core.oam.dev/v1alpha2/application/generator.go
index 73d2a37b..9d1b14e3 100644
--- a/pkg/controller/core.oam.dev/v1alpha2/application/generator.go
+++ b/pkg/controller/core.oam.dev/v1alpha2/application/generator.go
@@ -31,6 +31,7 @@ import (
 	"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/application/assemble"
 	"github.com/oam-dev/kubevela/pkg/cue/model/value"
 	"github.com/oam-dev/kubevela/pkg/cue/packages"
+	"github.com/oam-dev/kubevela/pkg/multicluster"
 	"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
 	"github.com/oam-dev/kubevela/pkg/oam/util"
 	"github.com/oam-dev/kubevela/pkg/utils"
@@ -123,7 +124,8 @@ func convertStepProperties(step *v1beta1.WorkflowStep, app *v1beta1.Application)
 }
 
 func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1beta1.ApplicationRevision, af *appfile.Appfile, cli client.Client) oamProvider.ComponentApply {
-	return func(comp common.ApplicationComponent, patcher *value.Value) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
+	return func(comp common.ApplicationComponent, patcher *value.Value, clusterName string) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
+		ctx := multicluster.ContextWithClusterName(context.Background(), clusterName)
 
 		wl, err := appParser.ParseWorkloadFromRevision(comp, appRev)
 		if err != nil {
@@ -137,11 +139,11 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
 		if err := af.SetOAMContract(manifest); err != nil {
 			return nil, nil, false, errors.WithMessage(err, "SetOAMContract")
 		}
-		if err := h.HandleComponentsRevision(context.TODO(), []*types.ComponentManifest{manifest}); err != nil {
+		if err := h.HandleComponentsRevision(ctx, []*types.ComponentManifest{manifest}); err != nil {
 			return nil, nil, false, errors.WithMessage(err, "HandleComponentsRevision")
 		}
 		if len(manifest.PackagedWorkloadResources) != 0 {
-			if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, manifest.PackagedWorkloadResources...); err != nil {
+			if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, manifest.PackagedWorkloadResources...); err != nil {
 				return nil, nil, false, errors.WithMessage(err, "cannot dispatch packaged workload resources")
 			}
 		}
@@ -152,12 +154,12 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
 
 		skipStandardWorkload := skipApplyWorkload(wl)
 		if !skipStandardWorkload {
-			if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, readyWorkload); err != nil {
+			if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, readyWorkload); err != nil {
 				return nil, nil, false, errors.WithMessage(err, "DispatchStandardWorkload")
 			}
 		}
 
-		if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, readyTraits...); err != nil {
+		if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, readyTraits...); err != nil {
 			return nil, nil, false, errors.WithMessage(err, "DispatchTraits")
 		}
 
@@ -169,7 +171,7 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
 		if !isHealth {
 			return nil, nil, false, nil
 		}
-		workload, traits, err := getComponentResources(manifest, skipStandardWorkload, cli)
+		workload, traits, err := getComponentResources(ctx, manifest, skipStandardWorkload, cli)
 		return workload, traits, true, err
 	}
 }
@@ -183,14 +185,14 @@ func skipApplyWorkload(wl *appfile.Workload) bool {
 	return false
 }
 
-func getComponentResources(manifest *types.ComponentManifest, skipStandardWorkload bool, cli client.Client) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
+func getComponentResources(ctx context.Context, manifest *types.ComponentManifest, skipStandardWorkload bool, cli client.Client) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
 	var (
 		workload *unstructured.Unstructured
 		traits   []*unstructured.Unstructured
 	)
 	if !skipStandardWorkload {
 		v := manifest.StandardWorkload.DeepCopy()
-		if err := cli.Get(context.Background(), client.ObjectKeyFromObject(manifest.StandardWorkload), v); err != nil {
+		if err := cli.Get(ctx, client.ObjectKeyFromObject(manifest.StandardWorkload), v); err != nil {
 			return nil, nil, err
 		}
 		workload = v
@@ -198,7 +200,7 @@ func getComponentResources(manifest *types.ComponentManifest, skipStandardWorklo
 
 	for _, trait := range manifest.Traits {
 		v := trait.DeepCopy()
-		if err := cli.Get(context.Background(), client.ObjectKeyFromObject(trait), v); err != nil {
+		if err := cli.Get(ctx, client.ObjectKeyFromObject(trait), v); err != nil {
 			return workload, nil, err
 		}
 		traits = append(traits, v)
diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/revision.go b/pkg/controller/core.oam.dev/v1alpha2/application/revision.go
index bf34d879..9f6152b5 100644
--- a/pkg/controller/core.oam.dev/v1alpha2/application/revision.go
+++ b/pkg/controller/core.oam.dev/v1alpha2/application/revision.go
@@ -582,6 +582,27 @@ func ComputeComponentRevisionHash(comp *types.ComponentManifest) (string, error)
 	return utils.ComputeSpecHash(&compRevisionHash)
 }
 
+// createOrGetResourceTracker create or get a resource tracker to manage all componentRevisions
+func (h *AppHandler) createOrGetResourceTracker(ctx context.Context) (*v1beta1.ResourceTracker, error) {
+	rt := &v1beta1.ResourceTracker{}
+	rtName := h.app.Name + "-" + h.app.Namespace
+	if err := h.r.Get(ctx, ktypes.NamespacedName{Name: rtName}, rt); err != nil {
+		if !apierrors.IsNotFound(err) {
+			return nil, err
+		}
+		rt.SetName(rtName)
+		rt.SetLabels(map[string]string{
+			oam.LabelAppName:      h.app.Name,
+			oam.LabelAppNamespace: h.app.Namespace,
+		})
+		rt.SetAnnotations(map[string]string{oam.AnnotationResourceTrackerLifeLong: "true"})
+		if err = h.r.Create(ctx, rt); err != nil {
+			return nil, err
+		}
+	}
+	return rt, nil
+}
+
 // createControllerRevision records snapshot of a component
 func (h *AppHandler) createControllerRevision(ctx context.Context, cm *types.ComponentManifest) error {
 	comp, err := componentManifest2Component(cm)
@@ -589,6 +610,10 @@ func (h *AppHandler) createControllerRevision(ctx context.Context, cm *types.Com
 		return err
 	}
 	revision, _ := utils.ExtractRevision(cm.RevisionName)
+	rt, err := h.createOrGetResourceTracker(ctx)
+	if err != nil {
+		return err
+	}
 	cr := &appsv1.ControllerRevision{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      cm.RevisionName,
@@ -596,9 +621,9 @@ func (h *AppHandler) createControllerRevision(ctx context.Context, cm *types.Com
 			OwnerReferences: []metav1.OwnerReference{
 				{
 					APIVersion: v1beta1.SchemeGroupVersion.String(),
-					Kind:       v1beta1.ApplicationKind,
-					Name:       h.app.Name,
-					UID:        h.app.UID,
+					Kind:       v1beta1.ResourceTrackerKind,
+					Name:       rt.GetName(),
+					UID:        rt.GetUID(),
 					Controller: pointer.BoolPtr(true),
 				},
 			},
@@ -757,6 +782,9 @@ func gatherUsingAppRevision(ctx context.Context, h *AppHandler) (map[string]bool
 		return nil, err
 	}
 	for _, rt := range rtList.Items {
+		if dispatch.IsLifeLongResourceTracker(rt) {
+			continue
+		}
 		appRev := dispatch.ExtractAppRevisionName(rt.Name, ns)
 		usingRevision[appRev] = true
 	}
diff --git a/pkg/oam/labels.go b/pkg/oam/labels.go
index e3e1b040..856ea759 100644
--- a/pkg/oam/labels.go
+++ b/pkg/oam/labels.go
@@ -117,6 +117,9 @@ const (
 	// AnnotationDefinitionRevisionName is used to specify the name of DefinitionRevision in component/trait definition
 	AnnotationDefinitionRevisionName = "definitionrevision.oam.dev/name"
 
+	// AnnotationResourceTrackerLifeLong is used to identify life-long resourcetracker which should only be recycled when application is deleted
+	AnnotationResourceTrackerLifeLong = "resourcetracker.oam.dev/life-long"
+
 	// AnnotationAddonsName records the name of initializer stored in configMap
 	AnnotationAddonsName = "addons.oam.dev/name"
 )
diff --git a/pkg/stdlib/op.cue b/pkg/stdlib/op.cue
index 4d82eb54..13e62aaa 100644
--- a/pkg/stdlib/op.cue
+++ b/pkg/stdlib/op.cue
@@ -109,13 +109,14 @@ import (
 		}
 	} @step(3)
 
-	target: yaml.Unmarshal(configMap.value.data["\(env)"])
-	apply:  #Steps & {
-		for key, val in target {
-			"\(key)": kube.#Apply & {
-				value: val
-				if val.metadata.labels != _|_ && val.metadata.labels["cluster.oam.dev/clusterName"] != _|_ {
-					cluster: val.metadata.labels["cluster.oam.dev/clusterName"]
+	patchedApp: yaml.Unmarshal(configMap.value.data["\(env)"])[context.name]
+	components: patchedApp.spec.components
+	apply:      #Steps & {
+		for key, comp in components {
+			"\(key)": #ApplyComponent & {
+				value: comp
+				if patchedApp.metadata.labels != _|_ && patchedApp.metadata.labels["cluster.oam.dev/clusterName"] != _|_ {
+					cluster: patchedApp.metadata.labels["cluster.oam.dev/clusterName"]
 				}
 			} @step(4)
 		}
diff --git a/pkg/stdlib/pkgs/oam.cue b/pkg/stdlib/pkgs/oam.cue
index 101e8c4c..b30d87ec 100644
--- a/pkg/stdlib/pkgs/oam.cue
+++ b/pkg/stdlib/pkgs/oam.cue
@@ -1,6 +1,7 @@
 #ApplyComponent: {
 	#provider: "oam"
 	#do:       "component-apply"
+	cluster:   *"" | string
 	value: {...}
 	patch?: {...}
 	...
diff --git a/pkg/utils/common/common.go b/pkg/utils/common/common.go
index 5f16eca0..36c35d1a 100644
--- a/pkg/utils/common/common.go
+++ b/pkg/utils/common/common.go
@@ -91,6 +91,23 @@ func InitBaseRestConfig() (Args, error) {
 	}, nil
 }
 
+// globalClient will be a client for whole command lifecycle
+var globalClient client.Client
+
+// SetGlobalClient will set a client for one cli command
+func SetGlobalClient(clt client.Client) error {
+	globalClient = clt
+	return nil
+}
+
+// GetClient will K8s client in args
+func GetClient() (client.Client, error) {
+	if globalClient != nil {
+		return globalClient, nil
+	}
+	return nil, errors.New("client not set, call SetGlobalClient first")
+}
+
 // HTTPGet will send GET http request with context
 func HTTPGet(ctx context.Context, url string) ([]byte, error) {
 	// Change NewRequest to NewRequestWithContext and pass context it
diff --git a/pkg/utils/config/config.go b/pkg/utils/config/config.go
deleted file mode 100644
index a40e71e3..00000000
--- a/pkg/utils/config/config.go
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package config
-
-import (
-	b64 "encoding/base64"
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"github.com/oam-dev/kubevela/pkg/utils/env"
-)
-
-// ReadConfigLine will read config from line
-func ReadConfigLine(line string) (string, string, error) {
-	ss := strings.SplitN(line, ":", 2)
-	if len(ss) != 2 {
-		return "", "", fmt.Errorf("config data is malformed: %s", line)
-	}
-	for i := range ss {
-		ss[i] = strings.TrimSpace(ss[i])
-	}
-	vDec, err := b64.StdEncoding.DecodeString(ss[1])
-	if err != nil {
-		return "", "", err
-	}
-	return ss[0], string(vDec), nil
-}
-
-// GetConfigsDir will get config from dir
-func GetConfigsDir(envName string) (string, error) {
-	cfgDir := filepath.Join(env.GetEnvDirByName(envName), "configs")
-	err := os.MkdirAll(cfgDir, 0700)
-	return cfgDir, err
-}
-
-// DeleteConfig will delete local config file
-func DeleteConfig(envName, configName string) error {
-	d, err := GetConfigsDir(envName)
-	if err != nil {
-		return err
-	}
-	cfgFile := filepath.Join(d, configName)
-	return os.RemoveAll(cfgFile)
-}
-
-// ReadConfig will read the config data from local
-func ReadConfig(envName, configName string) ([]byte, error) {
-	d, err := GetConfigsDir(envName)
-	if err != nil {
-		return nil, err
-	}
-	cfgFile := filepath.Join(d, configName)
-	b, err := os.ReadFile(filepath.Clean(cfgFile))
-	if os.IsNotExist(err) {
-		return []byte{}, nil
-	}
-	return b, err
-}
-
-// WriteConfig will write data into local config
-func WriteConfig(envName, configName string, data []byte) error {
-	d, err := GetConfigsDir(envName)
-	if err != nil {
-		return err
-	}
-	cfgFile := filepath.Join(d, configName)
-	return os.WriteFile(cfgFile, data, 0600)
-}
diff --git a/pkg/utils/env/env.go b/pkg/utils/env/env.go
index 64ac4d59..311ae101 100644
--- a/pkg/utils/env/env.go
+++ b/pkg/utils/env/env.go
@@ -18,151 +18,150 @@ package env
 
 import (
 	"context"
-	"encoding/json"
-	"errors"
 	"fmt"
 	"os"
 	"path/filepath"
 
-	corev1 "k8s.io/api/core/v1"
-	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	"cuelang.org/go/pkg/strings"
+
+	"github.com/pkg/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	k8stypes "k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
+	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
 	"github.com/oam-dev/kubevela/apis/types"
+	"github.com/oam-dev/kubevela/pkg/utils/apply"
+	"github.com/oam-dev/kubevela/pkg/utils/common"
 	"github.com/oam-dev/kubevela/pkg/utils/system"
 )
 
-// GetEnvDirByName will get env dir from name
-func GetEnvDirByName(name string) string {
-	envdir, _ := system.GetEnvDir()
-	return filepath.Join(envdir, name)
-}
+const (
+	// IndicatingLabel is label key indicating application is an env
+	IndicatingLabel = "cli.env.oam.dev/name"
+	// RawType is component type of raw
+	RawType = "raw"
+	// DefaultEnvName is name of default env
+	DefaultEnvName = "default"
+	// DefaultEnvNamespace is namespace of default env
+	DefaultEnvNamespace = "default"
+	// AppNameSchema is used to generate env app name
+	AppNameSchema = "vela-env-%s"
+	// AppNamePrefix is prefix of AppNameSchema
+	AppNamePrefix = "vela-env-"
+)
 
-// GetEnvByName will get env info by name
-func GetEnvByName(name string) (*types.EnvMeta, error) {
-	data, err := os.ReadFile(filepath.Join(GetEnvDirByName(name), system.EnvConfigName))
-	if err != nil {
-		if os.IsNotExist(err) {
-			return nil, fmt.Errorf("env %s not exist", name)
-		}
-		return nil, err
-	}
-	var meta types.EnvMeta
-	if err = json.Unmarshal(data, &meta); err != nil {
-		return nil, err
-	}
-	return &meta, nil
+// app2Env and env2App are helper convert functions
+func app2Env(app *v1beta1.Application) (*types.EnvMeta, error) {
+	namespace := getEnvNamespace(app)
+	env := types.EnvMeta{
+		Name:      strings.Replace(app.Name, AppNamePrefix, "", 1),
+		Namespace: namespace,
+		Current:   "",
+	}
+	return &env, nil
 }
 
-// CreateOrUpdateEnv will create or update env.
-// If it does not exist, create it and set to the new env.
-// If it exists, update it and set to the new env.
-func CreateOrUpdateEnv(ctx context.Context, c client.Client, envName string, envArgs *types.EnvMeta) (string, error) {
-
-	createOrUpdated := "created"
-	old, err := GetEnvByName(envName)
-	if err == nil {
-		createOrUpdated = "updated"
-		if envArgs.Domain == "" {
-			envArgs.Domain = old.Domain
-		}
-		if envArgs.Email == "" {
-			envArgs.Email = old.Email
-		}
-		if envArgs.Namespace == "" {
-			envArgs.Namespace = old.Namespace
-		}
+func env2App(meta *types.EnvMeta) *v1beta1.Application {
+	app := v1beta1.Application{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       v1beta1.ApplicationKind,
+			APIVersion: v1beta1.SchemeGroupVersion.String(),
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      fmt.Sprintf(AppNameSchema, meta.Name),
+			Namespace: types.DefaultKubeVelaNS,
+		},
+		Spec: v1beta1.ApplicationSpec{
+			Components: []common2.ApplicationComponent{},
+		},
 	}
 
-	if envArgs.Namespace == "" {
-		envArgs.Namespace = "default"
+	addNamespaceObjectIfNeeded(meta, &app)
+	labels := map[string]string{
+		IndicatingLabel: meta.Name,
 	}
+	app.SetLabels(labels)
 
-	var message = ""
-	// Check If Namespace Exists
-	if err := c.Get(ctx, k8stypes.NamespacedName{Name: envArgs.Namespace}, &corev1.Namespace{}); err != nil {
-		if !apierrors.IsNotFound(err) {
-			return message, err
-		}
-		// Create Namespace if not found
-		if err := c.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: envArgs.Namespace}}); err != nil {
-			return message, err
-		}
-	}
+	return &app
+}
 
-	data, err := json.Marshal(envArgs)
-	if err != nil {
-		return message, err
-	}
-	envdir, err := system.GetEnvDir()
+// getEnvAppByName and deleteAppByName are application operation helper functions
+func getEnvAppByName(envName string) (*v1beta1.Application, error) {
+	list, err := getEnvAppList()
 	if err != nil {
-		return message, err
+		return nil, err
 	}
-	subEnvDir := filepath.Join(envdir, envName)
-	if _, err = system.CreateIfNotExist(subEnvDir); err != nil {
-		return message, err
+	// match envName
+	for _, app := range list {
+		if app.Name == fmt.Sprintf(AppNameSchema, envName) {
+			return &app, nil
+		}
 	}
-	// nolint:gosec
-	if err = os.WriteFile(filepath.Join(subEnvDir, system.EnvConfigName), data, 0644); err != nil {
-		return message, err
+	if envName == DefaultEnvName {
+		_ = initDefaultEnv()
+		return getEnvAppByName(envName)
 	}
-	curEnvPath, err := system.GetCurrentEnvPath()
+	return nil, errors.Errorf("application %s not found", envName)
+}
+
+func deleteAppByName(name string) error {
+	clt, err := common.GetClient()
 	if err != nil {
-		return message, err
+		return errors.Wrap(err, "get client fail")
 	}
-	// nolint:gosec
-	if err = os.WriteFile(curEnvPath, []byte(envName), 0644); err != nil {
-		return message, err
+	app, err := getEnvAppByName(name)
+	if err != nil {
+		return err
 	}
-
-	message = fmt.Sprintf("environment %s %s, Namespace: %s", envName, createOrUpdated, envArgs.Namespace)
-	if envArgs.Email != "" {
-		message += fmt.Sprintf(", Email: %s", envArgs.Email)
+	err = clt.Delete(context.Background(), app)
+	if err != nil {
+		return err
 	}
-	return message, nil
+	return nil
 }
 
-// CreateEnv will only create. If env already exists, return error
-func CreateEnv(ctx context.Context, c client.Client, envName string, envArgs *types.EnvMeta) (string, error) {
-	_, err := GetEnvByName(envName)
-	if err == nil {
-		message := fmt.Sprintf("Env %s already exist", envName)
-		return message, errors.New(message)
-	}
-	return CreateOrUpdateEnv(ctx, c, envName, envArgs)
-}
+// following functions are CRUD of env
 
-// UpdateEnv will update Env, if env does not exist, return error
-func UpdateEnv(ctx context.Context, c client.Client, envName string, namespace string) (string, error) {
-	var message = ""
-	envMeta, err := GetEnvByName(envName)
+// CreateEnv will create e env.
+// Because Env equals to namespace, one env should not be updated
+func CreateEnv(envName string, envArgs *types.EnvMeta) error {
+	c, err := common.GetClient()
 	if err != nil {
-		return err.Error(), err
+		return err
 	}
-	if err := c.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: envMeta.Namespace}}); err != nil && !apierrors.IsAlreadyExists(err) {
-		return message, err
+	e := envArgs
+	nowEnv, err := GetEnvByName(envName)
+	if err == nil {
+		if nowEnv.Namespace != envArgs.Namespace {
+			return errors.Errorf("env %s has existed", envName)
+		}
+		return nil
 	}
-	envMeta.Namespace = namespace
-	data, err := json.Marshal(envMeta)
-	if err != nil {
-		return message, err
+	if e.Namespace == "" {
+		e.Namespace = "default"
 	}
-	envdir, err := system.GetEnvDir()
+
+	app := env2App(envArgs)
+	err = applyApp(context.TODO(), app, c)
 	if err != nil {
-		return message, err
+		return err
 	}
-	subEnvDir := filepath.Join(envdir, envName)
-	// nolint:gosec
-	if err = os.WriteFile(filepath.Join(subEnvDir, system.EnvConfigName), data, 0644); err != nil {
-		return message, err
+	return nil
+
+}
+
+// GetEnvByName will get env info by name
+func GetEnvByName(name string) (*types.EnvMeta, error) {
+	init, err := getEnvAppByName(name)
+	if err != nil {
+		return nil, errors.Wrap(err, "Env not exist")
 	}
-	message = "Update env succeed"
-	return message, err
+	return app2Env(init)
 }
 
 // ListEnvs will list all envs
+// if envName specified, return list that only contains one env
 func ListEnvs(envName string) ([]*types.EnvMeta, error) {
 	var envList []*types.EnvMeta
 	if envName != "" {
@@ -176,56 +175,42 @@ func ListEnvs(envName string) ([]*types.EnvMeta, error) {
 		envList = append(envList, env)
 		return envList, err
 	}
-	envDir, err := system.GetEnvDir()
+	apps, err := getEnvAppList()
 	if err != nil {
-		return envList, err
+		return nil, err
 	}
-	files, err := os.ReadDir(envDir)
-	if err != nil {
-		return envList, err
+	// if even one env is not exist, create a default env
+	if len(apps) == 0 {
+		err := initDefaultEnv()
+		if err != nil {
+			return nil, err
+		}
+		return ListEnvs(envName)
 	}
-	curEnv, err := GetCurrentEnvName()
+
+	curEnv, err := getCurrentEnvName()
 	if err != nil {
 		curEnv = types.DefaultEnvName
 	}
-	for _, f := range files {
-		if !f.IsDir() {
-			continue
-		}
-		data, err := os.ReadFile(filepath.Clean(filepath.Join(envDir, f.Name(), system.EnvConfigName)))
+	for i := range apps {
+		env, err := app2Env(&apps[i])
 		if err != nil {
+			fmt.Printf("error occurred while listing env:" + err.Error())
 			continue
 		}
-		var envMeta types.EnvMeta
-		if err = json.Unmarshal(data, &envMeta); err != nil {
-			continue
-		}
-		if curEnv == f.Name() {
-			envMeta.Current = "*"
+		if curEnv == env.Name {
+			env.Current = "*"
 		}
-		envList = append(envList, &envMeta)
+		envList = append(envList, env)
 	}
 	return envList, nil
 }
 
-// GetCurrentEnvName will get current env name
-func GetCurrentEnvName() (string, error) {
-	currentEnvPath, err := system.GetCurrentEnvPath()
-	if err != nil {
-		return "", err
-	}
-	data, err := os.ReadFile(filepath.Clean(currentEnvPath))
-	if err != nil {
-		return "", err
-	}
-	return string(data), nil
-}
-
-// DeleteEnv will delete env locally
+// DeleteEnv will delete env and its application
 func DeleteEnv(envName string) (string, error) {
 	var message string
 	var err error
-	curEnv, err := GetCurrentEnvName()
+	curEnv, err := getCurrentEnvName()
 	if err != nil {
 		return message, err
 	}
@@ -233,22 +218,40 @@ func DeleteEnv(envName string) (string, error) {
 		err = fmt.Errorf("you can't delete current using environment %s", curEnv)
 		return message, err
 	}
-	envdir, err := system.GetEnvDir()
+	err = deleteAppByName(envName)
 	if err != nil {
-		return message, err
+		return message, errors.Wrap(err, fmt.Sprintf("error deleting env %s", envName))
 	}
-	envPath := filepath.Join(envdir, envName)
-	if _, err := os.Stat(envPath); err != nil {
-		if os.IsNotExist(err) {
-			err = fmt.Errorf("%s does not exist", envName)
-			return message, err
-		}
+	message = "env" + envName + " deleted"
+	return message, err
+}
+
+// getCurrentEnvName will get current env name
+func getCurrentEnvName() (string, error) {
+	currentEnvPath, err := system.GetCurrentEnvPath()
+	if err != nil {
+		return "", err
 	}
-	if err = os.RemoveAll(envPath); err != nil {
-		return message, err
+	data, err := os.ReadFile(filepath.Clean(currentEnvPath))
+	if err != nil {
+		return "", err
 	}
-	message = envName + " deleted"
-	return message, err
+	return string(data), nil
+}
+
+// GetCurrentEnv will get current env, create default env if not exist
+func GetCurrentEnv() (*types.EnvMeta, error) {
+	envName, err := getCurrentEnvName()
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return nil, err
+		}
+		if err = initDefaultEnv(); err != nil {
+			return nil, err
+		}
+		envName = types.DefaultEnvName
+	}
+	return GetEnvByName(envName)
 }
 
 // SetEnv will set the current env to the specified one
@@ -269,3 +272,34 @@ func SetEnv(envName string) (string, error) {
 	msg = fmt.Sprintf("Set environment succeed, current environment is " + envName + ", namespace is " + envMeta.Namespace)
 	return msg, nil
 }
+
+// applyApp helps apply app
+func applyApp(ctx context.Context, app *v1beta1.Application, c client.Client) error {
+	applicator := apply.NewAPIApplicator(c)
+	err := applicator.Apply(ctx, app)
+	return err
+}
+
+// initDefaultEnv create default env if not exist
+func initDefaultEnv() error {
+	fmt.Println("Initializing default vela env...")
+	defaultEnv := &types.EnvMeta{Name: DefaultEnvName, Namespace: DefaultEnvNamespace}
+	app := env2App(defaultEnv)
+	clt, err := common.GetClient()
+	if err != nil {
+		return err
+	}
+	err = applyApp(context.Background(), app, clt)
+	if err != nil {
+		return err
+	}
+	currentEnvPath, err := system.GetCurrentEnvPath()
+	if err != nil {
+		return err
+	}
+	//nolint:gosec
+	if err = os.WriteFile(currentEnvPath, []byte(DefaultEnvName), 0644); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/pkg/utils/env/helper.go b/pkg/utils/env/helper.go
new file mode 100644
index 00000000..7f3db720
--- /dev/null
+++ b/pkg/utils/env/helper.go
@@ -0,0 +1,87 @@
+/*
+Copyright 2021 The KubeVela Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package env
+
+import (
+	"context"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
+	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
+	"github.com/oam-dev/kubevela/apis/types"
+	"github.com/oam-dev/kubevela/pkg/oam/util"
+	"github.com/oam-dev/kubevela/pkg/utils/common"
+)
+
+// getEnvAppList will filter application that represent an env
+func getEnvAppList() ([]v1beta1.Application, error) {
+	list := v1beta1.ApplicationList{}
+	clt, err := common.GetClient()
+	if err != nil {
+		return nil, err
+	}
+	ctx := context.Background()
+	matchLabels := metav1.LabelSelector{
+		MatchExpressions: []metav1.LabelSelectorRequirement{{
+			Key:      IndicatingLabel,
+			Operator: metav1.LabelSelectorOpExists,
+		}},
+	}
+	selector, err := metav1.LabelSelectorAsSelector(&matchLabels)
+	if err != nil {
+		return nil, err
+	}
+	err = clt.List(ctx, &list, &client.ListOptions{LabelSelector: selector})
+
+	if err != nil {
+		return nil, err
+	}
+	return list.Items, nil
+}
+
+func getEnvNamespace(application *v1beta1.Application) string {
+	namespace := DefaultEnvNamespace
+	for _, comp := range application.Spec.Components {
+		if comp.Type == RawType {
+			obj, err := util.RawExtension2Unstructured(&comp.Properties)
+			if err != nil {
+				return ""
+			}
+			return obj.GetName()
+		}
+	}
+	return namespace
+}
+
+// add namespace object if env namespace is not default
+func addNamespaceObjectIfNeeded(meta *types.EnvMeta, app *v1beta1.Application) {
+	if meta.Namespace != DefaultEnvNamespace {
+		app.Spec.Components = append(app.Spec.Components, common2.ApplicationComponent{
+			Name: meta.Namespace,
+			Type: RawType,
+			Properties: util.Object2RawExtension(map[string]interface{}{
+				"apiVersion": "v1",
+				"kind":       "Namespace",
+				"metadata": map[string]string{
+					"name": meta.Namespace,
+				},
+			}),
+		})
+	}
+}
diff --git a/pkg/utils/system/system.go b/pkg/utils/system/system.go
index ba693aa8..9f32e5de 100644
--- a/pkg/utils/system/system.go
+++ b/pkg/utils/system/system.go
@@ -17,11 +17,10 @@ limitations under the License.
 package system
 
 import (
-	"encoding/json"
 	"os"
 	"path/filepath"
 
-	"github.com/oam-dev/kubevela/apis/types"
+	"github.com/pkg/errors"
 )
 
 const defaultVelaHome = ".vela"
@@ -35,14 +34,23 @@ const (
 
 // GetVelaHomeDir return vela home dir
 func GetVelaHomeDir() (string, error) {
+	var velaHome string
 	if custom := os.Getenv(VelaHomeEnv); custom != "" {
-		return custom, nil
+		velaHome = custom
+	} else {
+		home, err := os.UserHomeDir()
+		if err != nil {
+			return "", err
+		}
+		velaHome = filepath.Join(home, defaultVelaHome)
 	}
-	home, err := os.UserHomeDir()
-	if err != nil {
-		return "", err
+	if _, err := os.Stat(velaHome); err != nil && os.IsNotExist(err) {
+		err := os.MkdirAll(velaHome, 0750)
+		if err != nil {
+			return "", errors.Wrap(err, "error when create vela home directory")
+		}
 	}
-	return filepath.Join(home, defaultVelaHome), nil
+	return velaHome, nil
 }
 
 // GetDefaultFrontendDir return default vela frontend dir
@@ -81,22 +89,14 @@ func GetCapabilityDir() (string, error) {
 	return filepath.Join(home, "capabilities"), nil
 }
 
-// GetEnvDir return KubeVela environments dir
-func GetEnvDir() (string, error) {
-	homedir, err := GetVelaHomeDir()
-	if err != nil {
-		return "", err
-	}
-	return filepath.Join(homedir, "envs"), nil
-}
-
 // GetCurrentEnvPath return current env config
 func GetCurrentEnvPath() (string, error) {
 	homedir, err := GetVelaHomeDir()
 	if err != nil {
 		return "", err
 	}
-	return filepath.Join(homedir, "curenv"), nil
+	envPath := filepath.Join(homedir, "curenv")
+	return envPath, nil
 }
 
 // InitDirs create dir if not exits
@@ -107,9 +107,6 @@ func InitDirs() error {
 	if err := InitCapCenterDir(); err != nil {
 		return err
 	}
-	if err := InitDefaultEnv(); err != nil {
-		return err
-	}
 	return nil
 }
 
@@ -133,39 +130,6 @@ func InitCapabilityDir() error {
 	return err
 }
 
-// EnvConfigName defines config
-const EnvConfigName = "config.json"
-
-// InitDefaultEnv create dir if not exits
-func InitDefaultEnv() error {
-	envDir, err := GetEnvDir()
-	if err != nil {
-		return err
-	}
-	defaultEnvDir := filepath.Join(envDir, types.DefaultEnvName)
-	exist, err := CreateIfNotExist(defaultEnvDir)
-	if err != nil {
-		return err
-	}
-	if exist {
-		return nil
-	}
-	data, _ := json.Marshal(&types.EnvMeta{Namespace: types.DefaultAppNamespace, Name: types.DefaultEnvName})
-	//nolint:gosec
-	if err = os.WriteFile(filepath.Join(defaultEnvDir, EnvConfigName), data, 0644); err != nil {
-		return err
-	}
-	curEnvPath, err := GetCurrentEnvPath()
-	if err != nil {
-		return err
-	}
-	//nolint:gosec
-	if err = os.WriteFile(curEnvPath, []byte(types.DefaultEnvName), 0644); err != nil {
-		return err
-	}
-	return nil
-}
-
 // CreateIfNotExist create dir if not exist
 func CreateIfNotExist(dir string) (bool, error) {
 	_, err := os.Stat(dir)
diff --git a/pkg/workflow/providers/oam/apply.go b/pkg/workflow/providers/oam/apply.go
index 99dfcfd9..b21617b3 100644
--- a/pkg/workflow/providers/oam/apply.go
+++ b/pkg/workflow/providers/oam/apply.go
@@ -39,7 +39,7 @@ const (
 )
 
 // ComponentApply apply oam component.
-type ComponentApply func(comp common.ApplicationComponent, patcher *value.Value) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error)
+type ComponentApply func(comp common.ApplicationComponent, patcher *value.Value, clusterName string) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error)
 
 type provider struct {
 	apply ComponentApply
@@ -58,7 +58,11 @@ func (p *provider) ApplyComponent(ctx wfContext.Context, v *value.Value, act wfT
 		return err
 	}
 	patcher, _ := v.LookupValue("patch")
-	workload, traits, healthy, err := p.apply(comp, patcher)
+	clusterName, err := v.GetString("cluster")
+	if err != nil {
+		clusterName = ""
+	}
+	workload, traits, healthy, err := p.apply(comp, patcher, clusterName)
 	if err != nil {
 		return err
 	}
diff --git a/references/appfile/api/appfile.go b/references/appfile/api/appfile.go
index 25e9dc21..151de855 100644
--- a/references/appfile/api/appfile.go
+++ b/references/appfile/api/appfile.go
@@ -32,7 +32,6 @@ import (
 	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
 	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
 	"github.com/oam-dev/kubevela/apis/types"
-	"github.com/oam-dev/kubevela/pkg/appfile/config"
 	"github.com/oam-dev/kubevela/pkg/builtin"
 	"github.com/oam-dev/kubevela/pkg/oam"
 	cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
@@ -64,16 +63,14 @@ type AppFile struct {
 	Services   map[string]Service `json:"services"`
 	Secrets    map[string]string  `json:"secrets,omitempty"`
 
-	configGetter config.Store
-	initialized  bool
+	initialized bool
 }
 
 // NewAppFile init an empty AppFile struct
 func NewAppFile() *AppFile {
 	return &AppFile{
-		Services:     make(map[string]Service),
-		Secrets:      make(map[string]string),
-		configGetter: &config.Local{},
+		Services: make(map[string]Service),
+		Secrets:  make(map[string]string),
 	}
 }
 
@@ -158,26 +155,10 @@ func (app *AppFile) BuildOAMApplication(env *types.EnvMeta, io cmdutil.IOStreams
 	servApp.SetNamespace(env.Namespace)
 	servApp.SetName(app.Name)
 	servApp.Spec.Components = []common.ApplicationComponent{}
+	if !silence {
+		io.Infof("parsing application components")
+	}
 	for serviceName, svc := range app.GetServices() {
-		if !silence {
-			io.Infof("\nRendering configs for service (%s)...\n", serviceName)
-		}
-		configname := svc.GetUserConfigName()
-		if configname != "" {
-			configData, err := app.configGetter.GetConfigData(configname, env.Name)
-			if err != nil {
-				return nil, nil, err
-			}
-			decodedData, err := config.DecodeConfigFormat(configData)
-			if err != nil {
-				return nil, nil, err
-			}
-			cm, err := config.ToConfigMap(app.configGetter, config.GenConfigMapName(app.Name, serviceName, configname), env.Name, decodedData)
-			if err != nil {
-				return nil, nil, err
-			}
-			auxiliaryObjects = append(auxiliaryObjects, cm)
-		}
 		comp, err := svc.RenderServiceToApplicationComponent(tm, serviceName)
 		if err != nil {
 			return nil, nil, err
diff --git a/references/appfile/app.go b/references/appfile/app.go
index 17c9e500..b1cb3c12 100644
--- a/references/appfile/app.go
+++ b/references/appfile/app.go
@@ -84,16 +84,6 @@ func LoadApplication(namespace, appName string, c common.Args) (*v1beta1.Applica
 	return app, nil
 }
 
-// Delete will delete an app along with it's appfile.
-func Delete(envName, appName string) error {
-	return GetStorage().Delete(envName, appName)
-}
-
-// Save will save appfile into default dir.
-func Save(app *api.Application, envName string) error {
-	return GetStorage().Save(app, envName)
-}
-
 // GetComponents will get oam components from Appfile.
 func GetComponents(app *v1beta1.Application) []string {
 	var components []string
diff --git a/references/appfile/driver/cfgmaps.go b/references/appfile/driver/cfgmaps.go
deleted file mode 100644
index 21af06a4..00000000
--- a/references/appfile/driver/cfgmaps.go
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package driver
-
-import (
-	"errors"
-
-	"github.com/oam-dev/kubevela/references/appfile/api"
-)
-
-// ConfigMapDriverName is local storage driver name
-const ConfigMapDriverName = "ConfigMap"
-
-// ConfigMap Storage
-type ConfigMap struct {
-	api.Driver
-}
-
-// NewConfigMapStorage get storage client of ConfigMap type
-func NewConfigMapStorage() *ConfigMap {
-	return &ConfigMap{}
-}
-
-// Name of local storage
-func (c *ConfigMap) Name() string {
-	return ConfigMapDriverName
-}
-
-// List applications from configmap storage
-func (c *ConfigMap) List(envName string) ([]*api.Application, error) {
-	// TODO support configmap storage
-	return nil, errors.New("not implement")
-}
-
-// Save applications from configmap storage
-func (c *ConfigMap) Save(app *api.Application, envName string) error {
-	// TODO support configmap storage
-	return errors.New("not implement")
-}
-
-// Delete applications from configmap storage
-func (c *ConfigMap) Delete(envName, appName string) error {
-	// TODO support configmap storage
-	return errors.New("not implement")
-}
-
-// Get applications from configmap storage
-func (c *ConfigMap) Get(envName, appName string) (*api.Application, error) {
-	// TODO support configmap storage
-	return nil, errors.New("not implement")
-}
diff --git a/references/appfile/driver/local.go b/references/appfile/driver/local.go
deleted file mode 100644
index 3ed823c4..00000000
--- a/references/appfile/driver/local.go
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package driver
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"time"
-
-	"sigs.k8s.io/yaml"
-
-	"github.com/oam-dev/kubevela/pkg/utils/env"
-	"github.com/oam-dev/kubevela/pkg/utils/system"
-	"github.com/oam-dev/kubevela/references/appfile/api"
-)
-
-// LocalDriverName is local storage driver name
-const LocalDriverName = "Local"
-
-// Local Storage
-type Local struct {
-	api.Driver
-}
-
-// NewLocalStorage get storage client of Local type
-func NewLocalStorage() *Local {
-	return &Local{}
-}
-
-// Name  is local storage driver name
-func (l *Local) Name() string {
-	return LocalDriverName
-}
-
-// Save application from local storage
-func (l *Local) Save(app *api.Application, envName string) error {
-	appDir, err := getApplicationDir(envName)
-	if err != nil {
-		return err
-	}
-	if app.CreateTime.IsZero() {
-		app.CreateTime = time.Now()
-	}
-	app.UpdateTime = time.Now()
-	out, err := yaml.Marshal(app)
-	if err != nil {
-		return err
-	}
-	//nolint:gosec
-	return os.WriteFile(filepath.Join(appDir, app.Name+".yaml"), out, 0644)
-}
-
-// Delete application from local storage
-func (l *Local) Delete(envName, appName string) error {
-	appDir, err := getApplicationDir(envName)
-	if err != nil {
-		return err
-	}
-	return os.Remove(filepath.Join(appDir, appName+".yaml"))
-}
-
-func getApplicationDir(envName string) (string, error) {
-	appDir := filepath.Join(env.GetEnvDirByName(envName), "applications")
-	_, err := system.CreateIfNotExist(appDir)
-	if err != nil {
-		err = fmt.Errorf("getting application directory from env %s failed, error: %w ", envName, err)
-	}
-	return appDir, err
-}
diff --git a/references/appfile/storage.go b/references/appfile/storage.go
deleted file mode 100644
index f794fe73..00000000
--- a/references/appfile/storage.go
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package appfile
-
-import (
-	"os"
-
-	"github.com/oam-dev/kubevela/pkg/utils/system"
-	"github.com/oam-dev/kubevela/references/appfile/api"
-	"github.com/oam-dev/kubevela/references/appfile/driver"
-)
-
-// Store application store client
-var store *Storage
-
-// Storage is common storage client，use it to get app and others resource
-type Storage struct {
-	api.Driver
-}
-
-// GetStorage will create storage driver from the system environment of "STORAGE_DRIVER"
-func GetStorage() *Storage {
-	driverName := os.Getenv(system.StorageDriverEnv)
-	if store == nil || store.Name() != driverName {
-		switch driverName {
-		// TODO mutli implement Storage
-		case driver.ConfigMapDriverName:
-			store = &Storage{driver.NewConfigMapStorage()}
-		case driver.LocalDriverName:
-			store = &Storage{driver.NewLocalStorage()}
-		default:
-			store = &Storage{driver.NewLocalStorage()}
-		}
-	}
-	return store
-}
-
-// Save application storage common implement
-func (s *Storage) Save(app *api.Application, envName string) error {
-	return s.Driver.Save(app, envName)
-}
-
-// Delete application storage common implement
-func (s *Storage) Delete(envName, appName string) error {
-	return s.Driver.Delete(envName, appName)
-}
diff --git a/references/cli/capability.go b/references/cli/capability.go
index 956871c8..c4262079 100644
--- a/references/cli/capability.go
+++ b/references/cli/capability.go
@@ -154,7 +154,7 @@ func NewCapUninstallCommand(c common2.Args, ioStreams cmdutil.IOStreams) *cobra.
 				}
 				name = l[1]
 			}
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
@@ -199,7 +199,7 @@ func NewCapListCommand(c common2.Args, ioStreams cmdutil.IOStreams) *cobra.Comma
 			if len(args) > 0 {
 				repoName = args[0]
 			}
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/cli.go b/references/cli/cli.go
index 565e3aac..1fa24335 100644
--- a/references/cli/cli.go
+++ b/references/cli/cli.go
@@ -87,7 +87,6 @@ func NewCommand() *cobra.Command {
 		NewPortForwardCommand(commandArgs, ioStream),
 		NewLogsCommand(commandArgs, ioStream),
 		NewEnvCommand(commandArgs, ioStream),
-		NewConfigCommand(ioStream),
 
 		// Workflows
 		NewWorkflowCommand(commandArgs, ioStream),
diff --git a/references/cli/components.go b/references/cli/components.go
index 6a065899..cc08d79d 100644
--- a/references/cli/components.go
+++ b/references/cli/components.go
@@ -51,7 +51,7 @@ func NewComponentsCommand(c common2.Args, ioStreams cmdutil.IOStreams) *cobra.Co
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			isDiscover, _ := cmd.Flags().GetBool("discover")
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/config.go b/references/cli/config.go
deleted file mode 100644
index 881dc53d..00000000
--- a/references/cli/config.go
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package cli
-
-import (
-	"bufio"
-	"bytes"
-	b64 "encoding/base64"
-	"fmt"
-	"os"
-	"strings"
-
-	"github.com/spf13/cobra"
-
-	"github.com/oam-dev/kubevela/apis/types"
-	"github.com/oam-dev/kubevela/pkg/utils/config"
-	cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
-)
-
-// Notes about config dir layout:
-// Under each env dir, there are individual files for each config.
-// The format is the same as k8s Secret.Data field with value base64 encoded.
-
-// NewConfigCommand will create command for config management for AppFile
-func NewConfigCommand(io cmdutil.IOStreams) *cobra.Command {
-	cmd := &cobra.Command{
-		Use:                   "config",
-		DisableFlagsInUseLine: true,
-		Short:                 "Manage configurations",
-		Long:                  "Manage configurations",
-		Annotations: map[string]string{
-			types.TagCommandType: types.TypeApp,
-		},
-	}
-	cmd.SetOut(io.Out)
-	cmd.AddCommand(
-		NewConfigListCommand(io),
-		NewConfigGetCommand(io),
-		NewConfigSetCommand(io),
-		NewConfigDeleteCommand(io),
-	)
-	return cmd
-}
-
-// NewConfigListCommand list all created configs
-func NewConfigListCommand(io cmdutil.IOStreams) *cobra.Command {
-	cmd := &cobra.Command{
-		Use:                   "ls",
-		Aliases:               []string{"list"},
-		DisableFlagsInUseLine: true,
-		Short:                 "List configs",
-		Long:                  "List all configs",
-		Example:               `vela config ls`,
-		RunE: func(cmd *cobra.Command, args []string) error {
-			return ListConfigs(io, cmd)
-		},
-		Annotations: map[string]string{
-			types.TagCommandType: types.TypeStart,
-		},
-	}
-	cmd.SetOut(io.Out)
-	return cmd
-}
-
-func getConfigDir(cmd *cobra.Command) (string, error) {
-	e, err := GetEnv(cmd)
-	if err != nil {
-		return "", err
-	}
-	return config.GetConfigsDir(e.Name)
-}
-
-// ListConfigs will list all configs
-func ListConfigs(ioStreams cmdutil.IOStreams, cmd *cobra.Command) error {
-	d, err := getConfigDir(cmd)
-	if err != nil {
-		return err
-	}
-	table := newUITable()
-	table.AddRow("NAME")
-	cfgList, err := listConfigs(d)
-	if err != nil {
-		return err
-	}
-
-	for _, name := range cfgList {
-		table.AddRow(name)
-	}
-	ioStreams.Info(table.String())
-	return nil
-}
-
-func listConfigs(dir string) ([]string, error) {
-	files, err := os.ReadDir(dir)
-	if err != nil {
-		return nil, err
-	}
-
-	l := []string{}
-	for _, f := range files {
-		l = append(l, f.Name())
-	}
-	return l, nil
-}
-
-// NewConfigGetCommand get config from local
-func NewConfigGetCommand(io cmdutil.IOStreams) *cobra.Command {
-	cmd := &cobra.Command{
-		Use:                   "get",
-		Aliases:               []string{"get"},
-		DisableFlagsInUseLine: true,
-		Short:                 "Get data for a config",
-		Long:                  "Get data for a config",
-		Example:               `vela config get <config-name>`,
-		RunE: func(cmd *cobra.Command, args []string) error {
-			return getConfig(args, io, cmd)
-		},
-		Annotations: map[string]string{
-			types.TagCommandType: types.TypeStart,
-		},
-	}
-	cmd.SetOut(io.Out)
-	return cmd
-}
-
-func getConfig(args []string, io cmdutil.IOStreams, cmd *cobra.Command) error {
-	e, err := GetEnv(cmd)
-	if err != nil {
-		return err
-	}
-	if len(args) < 1 {
-		return fmt.Errorf("must specify config name, vela config get <name>")
-	}
-	configName := args[0]
-	cfgData, err := config.ReadConfig(e.Name, configName)
-	if err != nil {
-		return err
-	}
-	io.Infof("Data:\n")
-	scanner := bufio.NewScanner(bytes.NewReader(cfgData))
-	for scanner.Scan() {
-		k, v, err := config.ReadConfigLine(scanner.Text())
-		if err != nil {
-			return err
-		}
-		io.Infof("  %s: %s\n", k, v)
-	}
-	return nil
-}
-
-// NewConfigSetCommand set a config data in local
-func NewConfigSetCommand(io cmdutil.IOStreams) *cobra.Command {
-	cmd := &cobra.Command{
-		Use:                   "set",
-		Aliases:               []string{"set"},
-		DisableFlagsInUseLine: true,
-		Short:                 "Set data for a config",
-		Long:                  "Set data for a config",
-		Example:               `vela config set <config-name> KEY=VALUE K2=V2`,
-		RunE: func(cmd *cobra.Command, args []string) error {
-			return setConfig(args, io, cmd)
-		},
-		Annotations: map[string]string{
-			types.TagCommandType: types.TypeStart,
-		},
-	}
-	cmd.SetOut(io.Out)
-	return cmd
-}
-
-func setConfig(args []string, io cmdutil.IOStreams, cmd *cobra.Command) error {
-	e, err := GetEnv(cmd)
-	if err != nil {
-		return err
-	}
-	envName := e.Name
-
-	if len(args) < 1 {
-		return fmt.Errorf("must specify config name, vela config set <name> KEY=VALUE")
-	}
-	configName := args[0]
-
-	input := map[string]string{}
-	for _, arg := range args[1:] {
-		ss := strings.SplitN(arg, "=", 2)
-		if len(ss) != 2 {
-			return fmt.Errorf("KV argument malformed: %s, should be KEY=VALUE", arg)
-		}
-		k := strings.TrimSpace(ss[0])
-		v := strings.TrimSpace(ss[1])
-		if _, ok := input[k]; ok {
-			return fmt.Errorf("KEY is not unique: %s", arg)
-		}
-		input[k] = v
-	}
-
-	cfgData, err := config.ReadConfig(envName, configName)
-	if err != nil {
-		return err
-	}
-
-	io.Infof("reading existing config data and merging with user input\n")
-	scanner := bufio.NewScanner(bytes.NewReader(cfgData))
-	for scanner.Scan() {
-		k, v, err := config.ReadConfigLine(scanner.Text())
-		if err != nil {
-			return err
-		}
-		input[k] = v
-	}
-
-	var out bytes.Buffer
-	for k, v := range input {
-		vEnc := b64.StdEncoding.EncodeToString([]byte(v))
-		out.WriteString(fmt.Sprintf("%s: %s\n", k, vEnc))
-	}
-	err = config.WriteConfig(envName, configName, out.Bytes())
-	if err != nil {
-		return err
-	}
-	io.Infof("config data saved successfully %s\n", emojiSucceed)
-	return nil
-}
-
-// NewConfigDeleteCommand delete a config from local
-func NewConfigDeleteCommand(io cmdutil.IOStreams) *cobra.Command {
-	cmd := &cobra.Command{
-		Use:                   "del",
-		Aliases:               []string{"del"},
-		DisableFlagsInUseLine: true,
-		Short:                 "Delete config",
-		Long:                  "Delete config",
-		Example:               `vela config del <config-name>`,
-		RunE: func(cmd *cobra.Command, args []string) error {
-			return deleteConfig(args, io, cmd)
-		},
-		Annotations: map[string]string{
-			types.TagCommandType: types.TypeStart,
-		},
-	}
-	cmd.SetOut(io.Out)
-	return cmd
-}
-
-func deleteConfig(args []string, io cmdutil.IOStreams, cmd *cobra.Command) error {
-	e, err := GetEnv(cmd)
-	if err != nil {
-		return err
-	}
-	if len(args) < 1 {
-		return fmt.Errorf("must specify config name, vela config get <name>")
-	}
-	configName := args[0]
-	err = config.DeleteConfig(e.Name, configName)
-	if err != nil {
-		return err
-	}
-	io.Infof("config (%s) deleted successfully\n", configName)
-	return nil
-}
diff --git a/references/cli/delete.go b/references/cli/delete.go
index ec41f190..cfc99884 100644
--- a/references/cli/delete.go
+++ b/references/cli/delete.go
@@ -54,7 +54,7 @@ func NewDeleteCommand(c common2.Args, ioStreams cmdutil.IOStreams) *cobra.Comman
 			C: c,
 		}
 		o.Client = newClient
-		o.Env, err = GetEnv(cmd)
+		o.Env, err = GetFlagEnvOrCurrent(cmd, c)
 		if err != nil {
 			return err
 		}
diff --git a/references/cli/dryrun.go b/references/cli/dryrun.go
index b8cb4f09..2971447b 100644
--- a/references/cli/dryrun.go
+++ b/references/cli/dryrun.go
@@ -72,7 +72,7 @@ func NewDryRunCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Command
 			return c.SetConfig()
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
-			velaEnv, err := GetEnv(cmd)
+			velaEnv, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/env.go b/references/cli/env.go
index 74ce8e3e..d75a718b 100644
--- a/references/cli/env.go
+++ b/references/cli/env.go
@@ -17,17 +17,14 @@ limitations under the License.
 package cli
 
 import (
-	"context"
 	"fmt"
-	"os"
 
+	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/oam-dev/kubevela/apis/types"
 	"github.com/oam-dev/kubevela/pkg/utils/common"
 	"github.com/oam-dev/kubevela/pkg/utils/env"
-	"github.com/oam-dev/kubevela/pkg/utils/system"
 	cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
 )
 
@@ -38,17 +35,20 @@ func NewEnvCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.Command {
 		DisableFlagsInUseLine: true,
 		Short:                 "Manage environments",
 		Long:                  "Manage environments",
+		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
+			return c.SetConfig()
+		},
 		Annotations: map[string]string{
 			types.TagCommandType: types.TypeApp,
 		},
 	}
 	cmd.SetOut(ioStream.Out)
-	cmd.AddCommand(NewEnvListCommand(ioStream), NewEnvInitCommand(c, ioStream), NewEnvSetCommand(ioStream), NewEnvDeleteCommand(ioStream))
+	cmd.AddCommand(NewEnvListCommand(c, ioStream), NewEnvInitCommand(c, ioStream), NewEnvSetCommand(c, ioStream), NewEnvDeleteCommand(c, ioStream))
 	return cmd
 }
 
 // NewEnvListCommand creates `env list` command for listing all environments
-func NewEnvListCommand(ioStream cmdutil.IOStreams) *cobra.Command {
+func NewEnvListCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:                   "ls",
 		Aliases:               []string{"list"},
@@ -57,6 +57,14 @@ func NewEnvListCommand(ioStream cmdutil.IOStreams) *cobra.Command {
 		Long:                  "List all environments",
 		Example:               `vela env ls [env-name]`,
 		RunE: func(cmd *cobra.Command, args []string) error {
+			clt, err := c.GetClient()
+			if err != nil {
+				return err
+			}
+			err = common.SetGlobalClient(clt)
+			if err != nil {
+				return err
+			}
 			return ListEnvs(args, ioStream)
 		},
 		Annotations: map[string]string{
@@ -70,23 +78,22 @@ func NewEnvListCommand(ioStream cmdutil.IOStreams) *cobra.Command {
 // NewEnvInitCommand creates `env init` command for initializing environments
 func NewEnvInitCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
 	var envArgs types.EnvMeta
-	ctx := context.Background()
 	cmd := &cobra.Command{
 		Use:                   "init <envName>",
 		DisableFlagsInUseLine: true,
 		Short:                 "Create environments",
 		Long:                  "Create environment and set the currently using environment",
-		Example:               `vela env init test --namespace test --email my@email.com`,
-		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
-			return c.SetConfig()
-		},
+		Example:               `vela env init test --namespace test`,
 		RunE: func(cmd *cobra.Command, args []string) error {
-			newClient, err := c.GetClient()
+			clt, err := c.GetClient()
 			if err != nil {
 				return err
 			}
-
-			return CreateOrUpdateEnv(ctx, newClient, &envArgs, args, ioStreams)
+			err = common.SetGlobalClient(clt)
+			if err != nil {
+				return err
+			}
+			return CreateEnv(&envArgs, args, ioStreams)
 		},
 		Annotations: map[string]string{
 			types.TagCommandType: types.TypeStart,
@@ -94,14 +101,11 @@ func NewEnvInitCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Comman
 	}
 	cmd.SetOut(ioStreams.Out)
 	cmd.Flags().StringVar(&envArgs.Namespace, "namespace", "", "specify K8s namespace for env")
-	cmd.Flags().StringVar(&envArgs.Email, "email", "", "specify email for production TLS Certificate notification")
-	cmd.Flags().StringVar(&envArgs.Domain, "domain", "", "specify domain your applications")
 	return cmd
 }
 
 // NewEnvDeleteCommand creates `env delete` command for deleting environments
-func NewEnvDeleteCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
-	ctx := context.Background()
+func NewEnvDeleteCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:                   "delete",
 		DisableFlagsInUseLine: true,
@@ -109,7 +113,15 @@ func NewEnvDeleteCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
 		Long:                  "Delete environment",
 		Example:               `vela env delete test`,
 		RunE: func(cmd *cobra.Command, args []string) error {
-			return DeleteEnv(ctx, args, ioStreams)
+			clt, err := c.GetClient()
+			if err != nil {
+				return err
+			}
+			err = common.SetGlobalClient(clt)
+			if err != nil {
+				return err
+			}
+			return DeleteEnv(args, ioStreams)
 		},
 		Annotations: map[string]string{
 			types.TagCommandType: types.TypeStart,
@@ -120,7 +132,7 @@ func NewEnvDeleteCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
 }
 
 // NewEnvSetCommand creates `env set` command for setting current environment
-func NewEnvSetCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
+func NewEnvSetCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:                   "set",
 		Aliases:               []string{"sw"},
@@ -129,6 +141,14 @@ func NewEnvSetCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
 		Long:                  "Set an environment as the current using one",
 		Example:               `vela env set test`,
 		RunE: func(cmd *cobra.Command, args []string) error {
+			clt, err := c.GetClient()
+			if err != nil {
+				return err
+			}
+			err = common.SetGlobalClient(clt)
+			if err != nil {
+				return err
+			}
 			return SetEnv(args, ioStreams)
 		},
 		Annotations: map[string]string{
@@ -142,7 +162,7 @@ func NewEnvSetCommand(ioStreams cmdutil.IOStreams) *cobra.Command {
 // ListEnvs shows info of all environments
 func ListEnvs(args []string, ioStreams cmdutil.IOStreams) error {
 	table := newUITable()
-	table.AddRow("NAME", "CURRENT", "NAMESPACE", "EMAIL", "DOMAIN")
+	table.AddRow("NAME", "NAMESPACE", "CURRENT")
 	var envName = ""
 	if len(args) > 0 {
 		envName = args[0]
@@ -152,14 +172,14 @@ func ListEnvs(args []string, ioStreams cmdutil.IOStreams) error {
 		return err
 	}
 	for _, env := range envList {
-		table.AddRow(env.Name, env.Current, env.Namespace, env.Email, env.Domain)
+		table.AddRow(env.Name, env.Namespace, env.Current)
 	}
 	ioStreams.Info(table.String())
 	return nil
 }
 
 // DeleteEnv deletes an environment
-func DeleteEnv(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) error {
+func DeleteEnv(args []string, ioStreams cmdutil.IOStreams) error {
 	if len(args) < 1 {
 		return fmt.Errorf("you must specify environment name for 'vela env delete' command")
 	}
@@ -173,18 +193,18 @@ func DeleteEnv(ctx context.Context, args []string, ioStreams cmdutil.IOStreams)
 	return nil
 }
 
-// CreateOrUpdateEnv creates or updates an environment
-func CreateOrUpdateEnv(ctx context.Context, c client.Client, envArgs *types.EnvMeta, args []string, ioStreams cmdutil.IOStreams) error {
+// CreateEnv creates an environment
+func CreateEnv(envArgs *types.EnvMeta, args []string, ioStreams cmdutil.IOStreams) error {
 	if len(args) < 1 {
 		return fmt.Errorf("you must specify environment name for 'vela env init' command")
 	}
 	envName := args[0]
 	envArgs.Name = envName
-	msg, err := env.CreateOrUpdateEnv(ctx, c, envName, envArgs)
+	err := env.CreateEnv(envName, envArgs)
 	if err != nil {
 		return err
 	}
-	ioStreams.Info(msg)
+	ioStreams.Infof("environment %s created\n", envName)
 	return nil
 }
 
@@ -202,26 +222,23 @@ func SetEnv(args []string, ioStreams cmdutil.IOStreams) error {
 	return nil
 }
 
-// GetEnv gets environment by name or current environment
+// GetFlagEnvOrCurrent gets environment by name or current environment
 // if no env exists, then init default environment
-func GetEnv(cmd *cobra.Command) (*types.EnvMeta, error) {
+func GetFlagEnvOrCurrent(cmd *cobra.Command, args common.Args) (*types.EnvMeta, error) {
+	clt, err := args.GetClient()
+	if err != nil {
+		return nil, err
+	}
+	err = common.SetGlobalClient(clt)
+	if err != nil {
+		return nil, errors.Wrap(err, "get flag env fail")
+	}
 	var envName string
-	var err error
 	if cmd != nil {
 		envName = cmd.Flag("env").Value.String()
 	}
 	if envName != "" {
 		return env.GetEnvByName(envName)
 	}
-	envName, err = env.GetCurrentEnvName()
-	if err != nil {
-		if !os.IsNotExist(err) {
-			return nil, err
-		}
-		if err = system.InitDefaultEnv(); err != nil {
-			return nil, err
-		}
-		envName = types.DefaultEnvName
-	}
-	return env.GetEnvByName(envName)
+	return env.GetCurrentEnv()
 }
diff --git a/references/cli/exec.go b/references/cli/exec.go
index d81680a6..9eef48fa 100644
--- a/references/cli/exec.go
+++ b/references/cli/exec.go
@@ -133,7 +133,7 @@ func (o *VelaExecOptions) Init(ctx context.Context, c *cobra.Command, argsIn []s
 	o.Cmd = c
 	o.Args = argsIn
 
-	env, err := GetEnv(o.Cmd)
+	env, err := GetFlagEnvOrCurrent(o.Cmd, o.VelaC)
 	if err != nil {
 		return err
 	}
diff --git a/references/cli/export.go b/references/cli/export.go
index 4b18763a..eb7a6f74 100644
--- a/references/cli/export.go
+++ b/references/cli/export.go
@@ -27,6 +27,7 @@ import (
 
 // NewExportCommand will create command for exporting deploy manifests from an AppFile
 func NewExportCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command {
+	appFilePath := new(string)
 	cmd := &cobra.Command{
 		Use:                   "export",
 		DisableFlagsInUseLine: true,
@@ -36,7 +37,7 @@ func NewExportCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command
 			types.TagCommandType: types.TypeStart,
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
-			velaEnv, err := GetEnv(cmd)
+			velaEnv, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
@@ -44,11 +45,7 @@ func NewExportCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command
 				IO:  ioStream,
 				Env: velaEnv,
 			}
-			filePath, err := cmd.Flags().GetString(appFilePath)
-			if err != nil {
-				return err
-			}
-			_, data, err := o.Export(filePath, velaEnv.Namespace, true, c)
+			_, data, err := o.Export(*appFilePath, velaEnv.Namespace, true, c)
 			if err != nil {
 				return err
 			}
@@ -58,6 +55,6 @@ func NewExportCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command
 	}
 	cmd.SetOut(ioStream.Out)
 
-	cmd.Flags().StringP(appFilePath, "f", "", "specify file path for appfile")
+	cmd.Flags().StringVarP(appFilePath, "file", "f", "", "specify file path for appfile")
 	return cmd
 }
diff --git a/references/cli/init.go b/references/cli/init.go
index 2b0a2341..b6b427ae 100644
--- a/references/cli/init.go
+++ b/references/cli/init.go
@@ -26,6 +26,7 @@ import (
 	"cuelang.org/go/cue"
 	"github.com/AlecAivazis/survey/v2"
 	"github.com/fatih/color"
+	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -72,7 +73,7 @@ func NewInitCommand(c common2.Args, ioStreams cmdutil.IOStreams) *cobra.Command
 				return err
 			}
 			o.client = newClient
-			o.Env, err = GetEnv(cmd)
+			o.Env, err = GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
@@ -146,27 +147,8 @@ func (o *appInitOptions) CheckEnv() error {
 	if o.Env.Namespace == "" {
 		o.Env.Namespace = "default"
 	}
-	o.Infof("Environment: %s, namespace: %s\n\n", o.Env.Name, o.Env.Namespace)
-	if o.Env.Domain == "" {
-		prompt := &survey.Input{
-			Message: "What is the domain of your application service (optional): ",
-		}
-		err := survey.AskOne(prompt, &o.Env.Domain)
-		if err != nil {
-			return fmt.Errorf("read domain err %w", err)
-		}
-	}
-	if o.Env.Email == "" {
-		prompt := &survey.Input{
-			Message: "What is your email (optional, used to generate certification): ",
-		}
-		err := survey.AskOne(prompt, &o.Env.Email)
-		if err != nil {
-			return fmt.Errorf("read email err %w", err)
-		}
-	}
-	if _, err := env.CreateOrUpdateEnv(context.Background(), o.client, o.Env.Name, o.Env); err != nil {
-		return err
+	if err := env.CreateEnv(o.Env.Name, o.Env); err != nil {
+		return errors.Wrap(err, "app init create namespace err")
 	}
 	return nil
 }
diff --git a/references/cli/livediff.go b/references/cli/livediff.go
index 81f9b184..e8de9c47 100644
--- a/references/cli/livediff.go
+++ b/references/cli/livediff.go
@@ -73,7 +73,7 @@ func NewLiveDiffCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Comma
 			return c.SetConfig()
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
-			velaEnv, err := GetEnv(cmd)
+			velaEnv, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/logs.go b/references/cli/logs.go
index 9105be66..89c818ad 100644
--- a/references/cli/logs.go
+++ b/references/cli/logs.go
@@ -57,7 +57,7 @@ func NewLogsCommand(c common.Args, ioStreams util.IOStreams) *cobra.Command {
 			ioStreams.Errorf("please specify app name")
 			return nil
 		}
-		env, err := GetEnv(cmd)
+		env, err := GetFlagEnvOrCurrent(cmd, c)
 		if err != nil {
 			return err
 		}
diff --git a/references/cli/ls.go b/references/cli/ls.go
index f074ef06..7d2675e9 100644
--- a/references/cli/ls.go
+++ b/references/cli/ls.go
@@ -44,7 +44,7 @@ func NewListCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
 			return c.SetConfig()
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/portforward.go b/references/cli/portforward.go
index 6a7a20c1..8baf89f0 100644
--- a/references/cli/portforward.go
+++ b/references/cli/portforward.go
@@ -124,7 +124,7 @@ func (o *VelaPortForwardOptions) Init(ctx context.Context, cmd *cobra.Command, a
 	o.Cmd = cmd
 	o.Args = argsIn
 
-	env, err := GetEnv(o.Cmd)
+	env, err := GetFlagEnvOrCurrent(o.Cmd, o.VelaC)
 	if err != nil {
 		return err
 	}
diff --git a/references/cli/show.go b/references/cli/show.go
index 0aedb484..b8708d70 100644
--- a/references/cli/show.go
+++ b/references/cli/show.go
@@ -74,7 +74,7 @@ func NewCapabilityShowCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra
 			}
 			ctx := context.Background()
 			capabilityName := args[0]
-			velaEnv, err := GetEnv(cmd)
+			velaEnv, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/status.go b/references/cli/status.go
index 387f5ed7..8396336c 100644
--- a/references/cli/status.go
+++ b/references/cli/status.go
@@ -106,7 +106,7 @@ func NewAppStatusCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Comm
 				os.Exit(1)
 			}
 			appName := args[0]
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				ioStreams.Errorf("Error: failed to get Env: %s", err)
 				return err
diff --git a/references/cli/traits.go b/references/cli/traits.go
index 42179a2b..8537667d 100644
--- a/references/cli/traits.go
+++ b/references/cli/traits.go
@@ -50,7 +50,7 @@ func NewTraitsCommand(c common2.Args, ioStreams cmdutil.IOStreams) *cobra.Comman
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			isDiscover, _ := cmd.Flags().GetBool("discover")
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/up.go b/references/cli/up.go
index 639b41fe..3ab14bce 100644
--- a/references/cli/up.go
+++ b/references/cli/up.go
@@ -31,12 +31,9 @@ import (
 	"github.com/oam-dev/kubevela/references/common"
 )
 
-var (
-	appFilePath string
-)
-
 // NewUpCommand will create command for applying an AppFile
 func NewUpCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command {
+	appFilePath := new(string)
 	cmd := &cobra.Command{
 		Use:                   "up",
 		DisableFlagsInUseLine: true,
@@ -49,7 +46,7 @@ func NewUpCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command {
 			return c.SetConfig()
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
-			velaEnv, err := GetEnv(cmd)
+			velaEnv, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
@@ -57,11 +54,7 @@ func NewUpCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command {
 			if err != nil {
 				return err
 			}
-			filePath, err := cmd.Flags().GetString(appFilePath)
-			if err != nil {
-				return err
-			}
-			fileContent, err := os.ReadFile(filepath.Clean(filePath))
+			fileContent, err := os.ReadFile(filepath.Clean(*appFilePath))
 			if err != nil {
 				return err
 			}
@@ -81,12 +74,12 @@ func NewUpCommand(c common2.Args, ioStream cmdutil.IOStreams) *cobra.Command {
 					IO:      ioStream,
 					Env:     velaEnv,
 				}
-				return o.Run(filePath, velaEnv.Namespace, c)
+				return o.Run(*appFilePath, velaEnv.Namespace, c)
 			}
 			return nil
 		},
 	}
 	cmd.SetOut(ioStream.Out)
-	cmd.Flags().StringP(appFilePath, "f", "", "specify file path for appfile")
+	cmd.Flags().StringVarP(appFilePath, "file", "f", "", "specify file path for appfile")
 	return cmd
 }
diff --git a/references/cli/workflow.go b/references/cli/workflow.go
index e7bdc82b..87fc62a3 100644
--- a/references/cli/workflow.go
+++ b/references/cli/workflow.go
@@ -60,7 +60,7 @@ func NewWorkflowSuspendCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra
 			if len(args) < 1 {
 				return fmt.Errorf("must specify application name")
 			}
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
@@ -99,7 +99,7 @@ func NewWorkflowResumeCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.
 			if len(args) < 1 {
 				return fmt.Errorf("must specify application name")
 			}
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
@@ -148,7 +148,7 @@ func NewWorkflowTerminateCommand(c common.Args, ioStream cmdutil.IOStreams) *cob
 			if len(args) < 1 {
 				return fmt.Errorf("must specify application name")
 			}
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
@@ -187,7 +187,7 @@ func NewWorkflowRestartCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra
 			if len(args) < 1 {
 				return fmt.Errorf("must specify application name")
 			}
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/cli/workloads.go b/references/cli/workloads.go
index 2ba9fcbc..b665ed77 100644
--- a/references/cli/workloads.go
+++ b/references/cli/workloads.go
@@ -38,7 +38,7 @@ func NewWorkloadsCommand(c common2.Args, ioStreams cmdutil.IOStreams) *cobra.Com
 			return c.SetConfig()
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
-			env, err := GetEnv(cmd)
+			env, err := GetFlagEnvOrCurrent(cmd, c)
 			if err != nil {
 				return err
 			}
diff --git a/references/common/application.go b/references/common/application.go
index 43f85a7e..20d9bd32 100644
--- a/references/common/application.go
+++ b/references/common/application.go
@@ -209,9 +209,6 @@ func RetrieveApplicationStatusByName(ctx context.Context, c client.Reader, appli
 
 // DeleteApp will delete app including server side
 func (o *DeleteOptions) DeleteApp() (string, error) {
-	if err := appfile.Delete(o.Env.Name, o.AppName); err != nil && !os.IsNotExist(err) {
-		return "", err
-	}
 	ctx := context.Background()
 	var app = new(corev1beta1.Application)
 	err := o.Client.Get(ctx, client.ObjectKey{Name: o.AppName, Namespace: o.Env.Namespace}, app)
@@ -443,9 +440,6 @@ func (o *AppfileOptions) Run(filePath, namespace string, c common.Args) error {
 
 // BaseAppFileRun starts an application according to Appfile
 func (o *AppfileOptions) BaseAppFileRun(result *BuildResult, args common.Args) error {
-	if err := o.saveToAppDir(result.appFile); err != nil {
-		return errors.Wrap(err, "save to app dir failed")
-	}
 
 	kubernetesComponent, err := appfile.ApplyTerraform(result.application, o.Kubecli, o.IO, o.Env.Namespace, args)
 	if err != nil {
@@ -457,11 +451,6 @@ func (o *AppfileOptions) BaseAppFileRun(result *BuildResult, args common.Args) e
 	return o.ApplyApp(result.application, result.scopes)
 }
 
-func (o *AppfileOptions) saveToAppDir(f *api.AppFile) error {
-	app := &api.Application{AppFile: f}
-	return appfile.Save(app, o.Env.Name)
-}
-
 // ApplyApp applys config resources for the app.
 // It differs by create and update:
 // - for create, it displays app status along with information of url, metrics, ssh, logging.
diff --git a/references/common/workload.go b/references/common/workload.go
index cbc611b6..fe06f926 100644
--- a/references/common/workload.go
+++ b/references/common/workload.go
@@ -139,5 +139,5 @@ func BaseComplete(env *types.EnvMeta, c common.Args, workloadName string, appNam
 	if err = appfile.SetWorkload(app, workloadName, tp, workloadData); err != nil {
 		return app, err
 	}
-	return app, appfile.Save(app, env.Name)
+	return app, nil
 }
diff --git a/vela-templates/addons/auto-gen/terraform-provider-azure.yaml b/vela-templates/addons/auto-gen/terraform-provider-azure.yaml
new file mode 100644
index 00000000..c7ede6ae
--- /dev/null
+++ b/vela-templates/addons/auto-gen/terraform-provider-azure.yaml
@@ -0,0 +1,46 @@
+apiVersion: core.oam.dev/v1beta1
+kind: Initializer
+metadata:
+  annotations:
+    addons.oam.dev/description: Kubernetes Terraform Controller for Azure
+    addons.oam.dev/name: terraform/provider-azure
+  name: terraform-provider-azure
+  namespace: default
+spec:
+  appTemplate:
+    spec:
+      components:
+      - name: azure-account-creds
+        properties:
+          apiVersion: v1
+          kind: Secret
+          metadata:
+            name: azure-account-creds
+            namespace: vela-system
+          stringData:
+            credentials: |
+              armClientID: [[ index .Args "ARM_CLIENT_ID" ]]
+              armClientSecret: [[ index .Args "ARM_CLIENT_SECRET" ]]
+              armSubscriptionID: [[ index .Args "ARM_SUBSCRIPTION_ID" ]]
+              armTenantID: [[ index .Args "ARM_TENANT_ID" ]]
+          type: Opaque
+        type: raw
+      - name: azure
+        properties:
+          apiVersion: terraform.core.oam.dev/v1beta1
+          kind: Provider
+          metadata:
+            name: azure
+            namespace: default
+          spec:
+            credentials:
+              secretRef:
+                key: credentials
+                name: azure-account-creds
+                namespace: vela-system
+              source: Secret
+            provider: azure
+        type: raw
+    status: {}
+status:
+  observedGeneration: 0
diff --git a/vela-templates/addons/auto-gen/terraform.yaml b/vela-templates/addons/auto-gen/terraform.yaml
index ebd1cf5e..d30400d7 100644
--- a/vela-templates/addons/auto-gen/terraform.yaml
+++ b/vela-templates/addons/auto-gen/terraform.yaml
@@ -351,6 +351,83 @@ spec:
                 apiVersion: terraform.core.oam.dev/v1beta1
                 kind: Configuration
         type: raw
+      - name: azure-database-mariadb
+        properties:
+          apiVersion: core.oam.dev/v1alpha2
+          kind: ComponentDefinition
+          metadata:
+            annotations:
+              definition.oam.dev/description: Terraform configuration for Azure Database
+                Mariadb
+              provider: azure
+            labels:
+              type: terraform
+            name: azure-database-mariadb
+            namespace: vela-system
+          spec:
+            schematic:
+              terraform:
+                configuration: |
+                  # Configure the Microsoft Azure Provider
+                  provider "azurerm" {
+                    features {}
+                  }
+
+                  resource "azurerm_resource_group" "example" {
+                    name = "tfex-mariadb-database-RG"
+                    location = "West Europe"
+                  }
+
+                  resource "azurerm_mariadb_server" "example" {
+                    name = "mariadb-svr-sample"
+                    location = azurerm_resource_group.example.location
+                    resource_group_name = azurerm_resource_group.example.name
+
+                    sku_name = "B_Gen5_2"
+
+                    storage_mb = 51200
+                    backup_retention_days = 7
+                    geo_redundant_backup_enabled = false
+
+                    administrator_login = var.username
+                    administrator_login_password = var.password
+                    version = "10.2"
+                    ssl_enforcement_enabled = true
+                  }
+
+                  resource "azurerm_mariadb_database" "example" {
+                    name = var.name
+                    resource_group_name = azurerm_resource_group.example.name
+                    server_name = azurerm_mariadb_server.example.name
+                    charset = "utf8"
+                    collation = "utf8_general_ci"
+                  }
+
+                  variable "name" {
+                    default = "mariadb_database"
+                    type = string
+                    description = "Database instance name"
+                  }
+
+                  variable "username" {
+                    default = "acctestun"
+                    type = string
+                    description = "Database instance username"
+                  }
+
+                  variable "password" {
+                    default = "H@Sh1CoR3!faked"
+                    type = string
+                    description = "Database instance password"
+                  }
+                providerRef:
+                  name: azure
+                  namespace: default
+            workload:
+              definition:
+                apiVersion: terraform.core.oam.dev/v1beta1
+                kind: Configuration
+        type: raw
     status: {}
   dependsOn:
   - ref:
diff --git a/vela-templates/addons/terraform-provider-azure/template.yaml b/vela-templates/addons/terraform-provider-azure/template.yaml
new file mode 100644
index 00000000..21f0f67a
--- /dev/null
+++ b/vela-templates/addons/terraform-provider-azure/template.yaml
@@ -0,0 +1,53 @@
+apiVersion: core.oam.dev/v1beta1
+kind: Initializer
+metadata:
+  annotations:
+    addons.oam.dev/description: Kubernetes Terraform Controller for Azure
+    addons.oam.dev/name: terraform/provider-azure
+  name: terraform-provider-azure
+  namespace: default
+spec:
+  appTemplate:
+    spec:
+      components:
+        - name: azure-account-creds
+          properties:
+            apiVersion: v1
+            kind: Secret
+            metadata:
+              name: azure-account-creds
+              namespace: vela-system
+            type: Opaque
+            stringData:
+              credentials: |
+                armClientID: [[ index .Args "ARM_CLIENT_ID" ]]
+                armClientSecret: [[ index .Args "ARM_CLIENT_SECRET" ]]
+                armSubscriptionID: [[ index .Args "ARM_SUBSCRIPTION_ID" ]]
+                armTenantID: [[ index .Args "ARM_TENANT_ID" ]]
+          type: raw
+        - name: azure
+          type: raw
+          properties:
+            apiVersion: terraform.core.oam.dev/v1beta1
+            kind: Provider
+            metadata:
+              name: azure
+              namespace: default
+            spec:
+              provider: azure
+              credentials:
+                source: Secret
+                secretRef:
+                  namespace: vela-system
+                  name: azure-account-creds
+                  key: credentials
+{{ range .ResourceFiles }}
+        - name: {{ .Name }}
+          type: raw
+          properties:
+{{ .Content | indent 12 }} {{ end }}
+{{ range .DefinitionFiles }}
+        - name: {{ .Name }}
+          type: raw
+          properties:
+{{ .Content | indent 12 }} {{ end }}
diff --git a/vela-templates/addons/terraform/definitions/terraform-azure-database-mariadb.yaml b/vela-templates/addons/terraform/definitions/terraform-azure-database-mariadb.yaml
new file mode 100644
index 00000000..24daaa7e
--- /dev/null
+++ b/vela-templates/addons/terraform/definitions/terraform-azure-database-mariadb.yaml
@@ -0,0 +1,73 @@
+apiVersion: core.oam.dev/v1alpha2
+kind: ComponentDefinition
+metadata:
+  name: azure-database-mariadb
+  namespace: vela-system
+  annotations:
+    provider: azure
+    definition.oam.dev/description: Terraform configuration for Azure Database Mariadb
+  labels:
+    type: terraform
+spec:
+  workload:
+    definition:
+      apiVersion: terraform.core.oam.dev/v1beta1
+      kind: Configuration
+  schematic:
+    terraform:
+      configuration: |
+        # Configure the Microsoft Azure Provider
+        provider "azurerm" {
+          features {}
+        }
+
+        resource "azurerm_resource_group" "example" {
+          name = "tfex-mariadb-database-RG"
+          location = "West Europe"
+        }
+
+        resource "azurerm_mariadb_server" "example" {
+          name = "mariadb-svr-sample"
+          location = azurerm_resource_group.example.location
+          resource_group_name = azurerm_resource_group.example.name
+
+          sku_name = "B_Gen5_2"
+
+          storage_mb = 51200
+          backup_retention_days = 7
+          geo_redundant_backup_enabled = false
+
+          administrator_login = var.username
+          administrator_login_password = var.password
+          version = "10.2"
+          ssl_enforcement_enabled = true
+        }
+
+        resource "azurerm_mariadb_database" "example" {
+          name = var.name
+          resource_group_name = azurerm_resource_group.example.name
+          server_name = azurerm_mariadb_server.example.name
+          charset = "utf8"
+          collation = "utf8_general_ci"
+        }
+
+        variable "name" {
+          default = "mariadb_database"
+          type = string
+          description = "Database instance name"
+        }
+
+        variable "username" {
+          default = "acctestun"
+          type = string
+          description = "Database instance username"
+        }
+
+        variable "password" {
+          default = "H@Sh1CoR3!faked"
+          type = string
+          description = "Database instance password"
+        }
+      providerRef:
+        name: azure
+        namespace: default



Test patch:
diff --git a/e2e/application/application_test.go b/e2e/application/application_test.go
index 8140c165..feeed3df 100644
--- a/e2e/application/application_test.go
+++ b/e2e/application/application_test.go
@@ -111,7 +111,7 @@ var ApplicationExecContext = func(context string, appName string) bool {
 
 var ApplicationPortForwardContext = func(context string, appName string) bool {
 	return ginkgo.Context(context, func() {
-		ginkgo.It("should get output of portward successfully", func() {
+		ginkgo.It("should get output of port-forward successfully", func() {
 			cli := fmt.Sprintf("vela port-forward %s 80:80 ", appName)
 			output, err := e2e.ExecAndTerminate(cli)
 			gomega.Expect(err).NotTo(gomega.HaveOccurred())
@@ -128,14 +128,6 @@ var ApplicationInitIntercativeCliContext = func(context string, appName string,
 				data := []struct {
 					q, a string
 				}{
-					{
-						q: "What is the domain of your application service (optional): ",
-						a: "testdomain",
-					},
-					{
-						q: "What is your email (optional, used to generate certification): ",
-						a: "test@mail",
-					},
 					{
 						q: "What would you like to name your application (required): ",
 						a: appName,
diff --git a/e2e/env/env_test.go b/e2e/env/env_test.go
index 437be0cc..c5d8fe89 100644
--- a/e2e/env/env_test.go
+++ b/e2e/env/env_test.go
@@ -32,7 +32,7 @@ var _ = ginkgo.Describe("Env", func() {
 	e2e.EnvInitContext("env init", envName)
 	e2e.EnvInitContext("env init another one", envName2)
 	e2e.EnvShowContext("env show", envName)
-	e2e.EnvSetContext("env sw", envName)
+	e2e.EnvSetContext("env set", envName)
 
 	ginkgo.Context("env list", func() {
 		ginkgo.It("should list all envs", func() {
diff --git a/pkg/appfile/appfile_test.go b/pkg/appfile/appfile_test.go
index 457faa37..ade79bb7 100644
--- a/pkg/appfile/appfile_test.go
+++ b/pkg/appfile/appfile_test.go
@@ -909,6 +909,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
 		hcl                        string
 		remote                     string
 		params                     map[string]interface{}
+		providerRef                *terraformtypes.Reference
 	}
 
 	type want struct {
@@ -967,7 +968,18 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
 				params: badParam,
 				hcl:    "abc",
 			},
-			want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)}},
+			want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)},
+		},
+
+		"terraform workload has a provider reference": {
+
+			args: args{
+				params:      badParam,
+				hcl:         "abc",
+				providerRef: &terraformtypes.Reference{Name: "azure", Namespace: "default"},
+			},
+			want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)},
+		},
 	}
 
 	for tcName, tc := range testcases {
@@ -1027,6 +1039,9 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
 				WriteConnectionSecretToReference: tc.args.writeConnectionSecretToRef,
 			}
 		}
+		if tc.args.providerRef != nil {
+			template.Terraform.ProviderReference = tc.args.providerRef
+		}
 
 		wl := &Workload{
 			FullTemplate: template,
diff --git a/pkg/utils/env/env_test.go b/pkg/utils/env/env_test.go
new file mode 100644
index 00000000..2aaa34af
--- /dev/null
+++ b/pkg/utils/env/env_test.go
@@ -0,0 +1,92 @@
+/*
+Copyright 2021 The KubeVela Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package env
+
+import (
+	"fmt"
+	"testing"
+
+	"gotest.tools/assert"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
+	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
+	"github.com/oam-dev/kubevela/pkg/oam/util"
+
+	"github.com/oam-dev/kubevela/apis/types"
+)
+
+func TestEnv(t *testing.T) {
+	testCases := []struct {
+		envName        string
+		namespace      string
+		wantComponents []common2.ApplicationComponent
+		labels         map[string]string
+	}{
+		{
+			envName:   "test-env",
+			namespace: "test-env-ns",
+			wantComponents: []common2.ApplicationComponent{
+				{
+					Name: "test-env-ns",
+					Type: RawType,
+					Properties: util.Object2RawExtension(map[string]interface{}{
+						"apiVersion": "v1",
+						"kind":       "Namespace",
+						"metadata":   map[string]string{"name": "test-env-ns"},
+					})},
+			},
+			labels: map[string]string{IndicatingLabel: "test-env"},
+		},
+
+		{
+			envName:        "test-env-default",
+			namespace:      "default",
+			wantComponents: []common2.ApplicationComponent{},
+			labels:         map[string]string{IndicatingLabel: "test-env-default"},
+		},
+	}
+	baseApp := v1beta1.Application{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       v1beta1.ApplicationKind,
+			APIVersion: v1beta1.SchemeGroupVersion.String(),
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      "",
+			Namespace: types.DefaultKubeVelaNS,
+		},
+		Spec: v1beta1.ApplicationSpec{
+			Components: []common2.ApplicationComponent{}}}
+	for _, c := range testCases {
+		env := &types.EnvMeta{
+			Name:      c.envName,
+			Namespace: c.namespace,
+		}
+		rightApp := baseApp.DeepCopy()
+		rightApp.ObjectMeta.Name = fmt.Sprintf(AppNameSchema, c.envName)
+		rightApp.ObjectMeta.Labels = c.labels
+		rightApp.Spec.Components = c.wantComponents
+
+		generatedApp := env2App(env)
+		assert.DeepEqual(t, generatedApp, rightApp)
+
+		generatedEnv, err := app2Env(rightApp)
+		assert.NilError(t, err)
+		assert.DeepEqual(t, generatedEnv, env)
+	}
+}
diff --git a/pkg/workflow/providers/oam/apply_test.go b/pkg/workflow/providers/oam/apply_test.go
index 39e13281..65a87581 100644
--- a/pkg/workflow/providers/oam/apply_test.go
+++ b/pkg/workflow/providers/oam/apply_test.go
@@ -115,7 +115,7 @@ func TestLoadComponent(t *testing.T) {
 
 var testHealthy bool
 
-func simpleComponentApplyForTest(comp common.ApplicationComponent, _ *value.Value) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
+func simpleComponentApplyForTest(comp common.ApplicationComponent, _ *value.Value, _ string) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
 	workload := new(unstructured.Unstructured)
 	workload.UnmarshalJSON([]byte(`{
   "apiVersion": "v1",
diff --git a/references/appfile/api/appfile_test.go b/references/appfile/api/appfile_test.go
index 3fe7cb7a..ba2370f8 100644
--- a/references/appfile/api/appfile_test.go
+++ b/references/appfile/api/appfile_test.go
@@ -30,7 +30,6 @@ import (
 	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
 	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
 	"github.com/oam-dev/kubevela/apis/types"
-	"github.com/oam-dev/kubevela/pkg/appfile/config"
 	"github.com/oam-dev/kubevela/pkg/oam"
 	"github.com/oam-dev/kubevela/pkg/oam/util"
 	cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
@@ -137,7 +136,7 @@ func TestBuildOAMApplication2(t *testing.T) {
 			In:  os.Stdin,
 			Out: os.Stdout,
 		}, tm, false)
-		assert.Equal(t, nil, err)
+		assert.NoError(t, err)
 		assert.Equal(t, tcase.expectApp, o)
 	}
 }
@@ -168,19 +167,6 @@ services:
     cmd: ["node", "server.js"]
 `
 
-	yamlWithConfig := `name: myapp
-services:
-  express-server:
-    type: withconfig
-    image: oamdev/testapp:v1
-    cmd: ["node", "server.js"]
-    route:
-      domain: example.com
-      http:
-        "/": 8080
-    config: test
-`
-
 	templateWebservice := `parameter: #webservice
 #webservice: {
   cmd: [...string]
@@ -216,25 +202,6 @@ output: {
     command: parameter.cmd
   }
 }`
-	templateWithConfig := `parameter: #withconfig
-#withconfig: {
-  cmd: [...string]
-  image: string
-}
-
-output: {
-  apiVersion: "test.oam.dev/v1"
-  kind: "WebService"
-  metadata: {
-    name: context.name
-  }
-  spec: {
-    image: parameter.image
-    command: parameter.cmd
-    env: context.config
-  }
-}
-`
 	templateRoute := `parameter: #route
 #route: {
   domain: string
@@ -324,22 +291,6 @@ outputs: ingress: {
 	// TODO application 那边补测试:
 	// 2. 1对多的情况，多对1 的情况
 
-	fakeConfigData2 := []map[string]string{{
-		"name":  "test",
-		"value": "test-value",
-	}}
-
-	ac3cm := &corev1.ConfigMap{
-		TypeMeta: metav1.TypeMeta{
-			APIVersion: "v1",
-			Kind:       "ConfigMap",
-		},
-		Data: map[string]string{
-			"test": "test-value",
-		},
-	}
-	ac3cm.SetName("kubevela-myapp-express-server-test")
-
 	health := &v1alpha2.HealthScope{
 		TypeMeta: metav1.TypeMeta{
 			APIVersion: v1alpha2.HealthScopeGroupVersionKind.GroupVersion().String(),
@@ -402,21 +353,6 @@ outputs: ingress: {
 				err: ErrImageNotDefined,
 			},
 		},
-		"config data should be set, add return configmap objects": {
-			args: args{
-				appfileData: yamlWithConfig,
-				workloadTemplates: map[string]string{
-					"withconfig": templateWithConfig,
-				},
-				traitTemplates: map[string]string{
-					"route": templateRoute,
-				},
-			},
-			want: want{
-				app:  ac3,
-				objs: []oam.Object{ac3cm, health},
-			},
-		},
 	}
 
 	io := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}
@@ -424,9 +360,6 @@ outputs: ingress: {
 		t.Run(caseName, func(t *testing.T) {
 
 			app := NewAppFile()
-			app.configGetter = &config.Fake{
-				Data: fakeConfigData2,
-			}
 			err := yaml.Unmarshal([]byte(c.args.appfileData), app)
 			if err != nil {
 				t.Fatal(err)
diff --git a/references/appfile/driver/cfgmaps_test.go b/references/appfile/driver/cfgmaps_test.go
deleted file mode 100644
index 8fb50b62..00000000
--- a/references/appfile/driver/cfgmaps_test.go
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package driver
-
-import (
-	"reflect"
-	"testing"
-
-	"github.com/oam-dev/kubevela/references/appfile/api"
-)
-
-func TestConfigMapDelete(t *testing.T) {
-	type args struct {
-		envName string
-		appName string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ConfigMap{}
-			if err := c.Delete(tt.args.envName, tt.args.appName); (err != nil) != tt.wantErr {
-				t.Errorf("Delete() error = %v, wantErr %v", err, tt.wantErr)
-			}
-		})
-	}
-}
-
-func TestConfigMapGet(t *testing.T) {
-	type args struct {
-		envName string
-		appName string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    *api.Application
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ConfigMap{}
-			got, err := c.Get(tt.args.envName, tt.args.appName)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("Get() got = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestConfigMapList(t *testing.T) {
-	type args struct {
-		envName string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    []*api.Application
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ConfigMap{}
-			got, err := c.List(tt.args.envName)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("List() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("List() got = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestConfigMapName(t *testing.T) {
-	tests := []struct {
-		name string
-		want string
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ConfigMap{}
-			if got := c.Name(); got != tt.want {
-				t.Errorf("Name() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestConfigMapSave(t *testing.T) {
-	type args struct {
-		app     *api.Application
-		envName string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ConfigMap{}
-			if err := c.Save(tt.args.app, tt.args.envName); (err != nil) != tt.wantErr {
-				t.Errorf("Save() error = %v, wantErr %v", err, tt.wantErr)
-			}
-		})
-	}
-}
diff --git a/references/appfile/driver/local_test.go b/references/appfile/driver/local_test.go
deleted file mode 100644
index 4e920e92..00000000
--- a/references/appfile/driver/local_test.go
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package driver
-
-import (
-	"os"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"testing"
-
-	"sigs.k8s.io/yaml"
-
-	"github.com/oam-dev/kubevela/references/appfile/api"
-)
-
-var dir string
-var afile *api.AppFile
-var appName = "testsvc"
-var envName = "default"
-
-func init() {
-	dir, _ = getApplicationDir(envName)
-	afile = api.NewAppFile()
-	afile.Name = appName
-	svcs := make(map[string]api.Service)
-	svcs["wordpress"] = map[string]interface{}{
-		"type":  "webservice",
-		"image": "wordpress:php7.4-apache",
-		"port":  "80",
-		"cpu":   "1",
-		"route": "",
-	}
-	afile.Services = svcs
-	out, _ := yaml.Marshal(afile)
-	_ = os.WriteFile(filepath.Join(dir, appName+".yaml"), out, 0644)
-}
-
-func TestLocalDelete(t *testing.T) {
-	type args struct {
-		envName string
-		appName string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
-	}{
-		{"testLocalDelete1", args{envName: envName, appName: appName}, false},
-		{"testLocalDelete2", args{envName: envName, appName: "test"}, true},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			l := &Local{}
-			if err := l.Delete(tt.args.envName, tt.args.appName); (err != nil) != tt.wantErr {
-				t.Errorf("Delete() error = %v, wantErr %v", err, tt.wantErr)
-			}
-		})
-	}
-}
-
-func TestLocalSave(t *testing.T) {
-	type args struct {
-		app     *api.Application
-		envName string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
-	}{
-		{"TestLocal_Save1", args{&api.Application{AppFile: afile, Tm: nil}, envName}, false},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			l := &Local{}
-			if err := l.Save(tt.args.app, tt.args.envName); (err != nil) != tt.wantErr {
-				t.Errorf("Save() error = %v, wantErr %v", err, tt.wantErr)
-			}
-		})
-	}
-}
-
-func TestLocalName(t *testing.T) {
-	tests := []struct {
-		name string
-		want string
-	}{
-		{"testDriverName", "Local"},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			l := &Local{}
-			if got := l.Name(); got != tt.want {
-				t.Errorf("Name() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestNewLocalStorage(t *testing.T) {
-	tests := []struct {
-		name string
-		want *Local
-	}{
-		{"testNewLocal", &Local{}},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := NewLocalStorage(); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("NewLocalStorage() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestGetApplicationDir(t *testing.T) {
-	type args struct {
-		envName string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    string
-		wantErr bool
-	}{
-		{"testGetApplicationDir", args{envName: envName}, "/envs/default/applications", false},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := getApplicationDir(tt.args.envName)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("getApplicationDir() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !strings.Contains(got, tt.want) {
-				t.Errorf("getApplicationDir() got = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/references/appfile/storage_test.go b/references/appfile/storage_test.go
deleted file mode 100644
index 8f2e887e..00000000
--- a/references/appfile/storage_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package appfile
-
-import (
-	"os"
-	"testing"
-
-	"github.com/oam-dev/kubevela/pkg/utils/system"
-	"github.com/oam-dev/kubevela/references/appfile/driver"
-)
-
-func TestGetStorage(t *testing.T) {
-	_ = os.Setenv(system.StorageDriverEnv, driver.ConfigMapDriverName)
-
-	store := &Storage{driver.NewConfigMapStorage()}
-	tests := []struct {
-		name string
-		want *Storage
-	}{
-		{name: "TestGetStorage_ConfigMap", want: store},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := GetStorage(); got.Name() != tt.want.Name() {
-				t.Errorf("GetStorage() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/references/cli/config_test.go b/references/cli/config_test.go
deleted file mode 100644
index 1b109b8c..00000000
--- a/references/cli/config_test.go
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-Copyright 2021 The KubeVela Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package cli
-
-import (
-	"bytes"
-	"os"
-	"strings"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-
-	"github.com/oam-dev/kubevela/pkg/utils/system"
-	cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
-)
-
-func TestConfigCommand(t *testing.T) {
-	// Set VELA_HOME to local
-	assert.NoError(t, os.Setenv(system.VelaHomeEnv, ".test_vela"))
-	home, err := system.GetVelaHomeDir()
-	assert.NoError(t, err)
-	assert.Equal(t, true, strings.HasSuffix(home, ".test_vela"))
-	defer os.RemoveAll(home)
-
-	// Create Default Env
-	err = system.InitDefaultEnv()
-	assert.NoError(t, err)
-
-	// vela config set test a=b
-	io := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}
-	err = setConfig([]string{"test", "a=b"}, io, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// vela config get test
-	var b bytes.Buffer
-	io.Out = &b
-	err = getConfig([]string{"test"}, io, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, "Data:\n  a: b\n", b.String())
-
-	// vela config set test2 c=d
-	io.Out = os.Stdout
-	err = setConfig([]string{"test2", "c=d"}, io, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// vela config ls
-	b = bytes.Buffer{}
-	io.Out = &b
-	err = ListConfigs(io, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, "NAME \ntest \ntest2\n", b.String())
-
-	// vela config del test
-	io.Out = os.Stdout
-	err = deleteConfig([]string{"test"}, io, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// vela config ls
-	b = bytes.Buffer{}
-	io.Out = &b
-	err = ListConfigs(io, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, "NAME \ntest2\n", b.String())
-}
diff --git a/references/cli/env_test.go b/references/cli/env_test.go
index a247ef27..1ae820ff 100644
--- a/references/cli/env_test.go
+++ b/references/cli/env_test.go
@@ -17,108 +17,19 @@ limitations under the License.
 package cli
 
 import (
-	"bytes"
-	"context"
 	"os"
 	"strings"
 	"testing"
 
-	"github.com/crossplane/crossplane-runtime/pkg/test"
-	"github.com/spf13/cobra"
 	"github.com/stretchr/testify/assert"
 
-	"github.com/oam-dev/kubevela/apis/types"
-	"github.com/oam-dev/kubevela/pkg/utils/common"
-	"github.com/oam-dev/kubevela/pkg/utils/env"
 	"github.com/oam-dev/kubevela/pkg/utils/system"
-	cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
 )
 
 func TestENV(t *testing.T) {
-	ctx := context.Background()
-
 	assert.NoError(t, os.Setenv(system.VelaHomeEnv, ".test_vela"))
 	home, err := system.GetVelaHomeDir()
 	assert.NoError(t, err)
 	assert.Equal(t, true, strings.HasSuffix(home, ".test_vela"))
 	defer os.RemoveAll(home)
-	// Create Default Env
-	err = system.InitDefaultEnv()
-	assert.NoError(t, err)
-
-	// check and compare create default env success
-	curEnvName, err := env.GetCurrentEnvName()
-	assert.NoError(t, err)
-	assert.Equal(t, "default", curEnvName)
-	gotEnv, err := GetEnv(nil)
-	assert.NoError(t, err)
-	assert.Equal(t, &types.EnvMeta{
-		Namespace: "default",
-		Name:      "default",
-	}, gotEnv)
-
-	ioStream := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}
-	exp := &types.EnvMeta{
-		Namespace: "test1",
-		Name:      "env1",
-	}
-	client := test.NewMockClient()
-	// Create env1
-	err = CreateOrUpdateEnv(ctx, client, exp, []string{"env1"}, ioStream)
-	assert.NoError(t, err)
-
-	// check and compare create env success
-	curEnvName, err = env.GetCurrentEnvName()
-	assert.NoError(t, err)
-	assert.Equal(t, "env1", curEnvName)
-	gotEnv, err = GetEnv(nil)
-	assert.NoError(t, err)
-	assert.Equal(t, exp, gotEnv)
-
-	// List all env
-	var b bytes.Buffer
-	ioStream.Out = &b
-	err = ListEnvs([]string{}, ioStream)
-	assert.NoError(t, err)
-	assert.Equal(t, "NAME   \tCURRENT\tNAMESPACE\tEMAIL\tDOMAIN\ndefault\t       \tdefault  \t     \t      \nenv1   \t*      \ttest1    \t     \t      \n", b.String())
-	b.Reset()
-	err = ListEnvs([]string{"env1"}, ioStream)
-	assert.NoError(t, err)
-	assert.Equal(t, "NAME\tCURRENT\tNAMESPACE\tEMAIL\tDOMAIN\nenv1\t       \ttest1    \t     \t      \n", b.String())
-	ioStream.Out = os.Stdout
-
-	// can not delete current env
-	err = DeleteEnv(ctx, []string{"env1"}, ioStream)
-	assert.Error(t, err)
-
-	// set as default env
-	err = SetEnv([]string{"default"}, ioStream)
-	assert.NoError(t, err)
-
-	// check env set success
-	gotEnv, err = GetEnv(nil)
-	assert.NoError(t, err)
-	assert.Equal(t, &types.EnvMeta{
-		Namespace: "default",
-		Name:      "default",
-	}, gotEnv)
-
-	// delete env
-	err = DeleteEnv(ctx, []string{"env1"}, ioStream)
-	assert.NoError(t, err)
-
-	// can not set as a non-exist env
-	err = SetEnv([]string{"env1"}, ioStream)
-	assert.Error(t, err)
-
-	// set success
-	err = SetEnv([]string{"default"}, ioStream)
-	assert.NoError(t, err)
-}
-
-func TestEnvInitCommandPersistentPreRunE(t *testing.T) {
-	io := cmdutil.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}
-	fakeC := common.Args{}
-	cmd := NewEnvInitCommand(fakeC, io)
-	assert.Nil(t, cmd.PersistentPreRunE(new(cobra.Command), []string{}))
 }
diff --git a/test/e2e-test/application_test.go b/test/e2e-test/application_test.go
index abc7c9eb..5efe61ca 100644
--- a/test/e2e-test/application_test.go
+++ b/test/e2e-test/application_test.go
@@ -138,8 +138,8 @@ var _ = Describe("Application Normal tests", func() {
 					return fmt.Errorf("expect revision %d != real %d", revisionNum, gotCR.Revision)
 				}
 				ctrlOwner := metav1.GetControllerOf(gotCR)
-				if ctrlOwner == nil || ctrlOwner.Kind != v1beta1.ApplicationKind {
-					return fmt.Errorf("expect ControllerRevision is control-owned by an Application")
+				if ctrlOwner == nil || ctrlOwner.Kind != v1beta1.ResourceTrackerKind {
+					return fmt.Errorf("expect ControllerRevision is control-owned by a ResourceTracker")
 				}
 				return nil
 			},