From c9b99355503ce84437378e00b77bfc9eae0dc7c1 Mon Sep 17 00:00:00 2001 From: Jared Watts Date: Tue, 4 Dec 2018 04:11:29 -0800 Subject: [PATCH 1/5] docs: clean up and update content for adding cloud providers and deploying workloads Signed-off-by: Jared Watts --- .../{kubernetes.yaml => cluster.yaml} | 0 docs/README.md | 2 + docs/cloud-providers/aws/aws-provider.md | 110 ++---------- docs/cloud-providers/azure/azure-provider.md | 30 ++-- docs/cloud-providers/gcp/gcp-provider.md | 107 ++++++----- docs/deploy.md | 131 +++++++++++++- docs/workloads/aws/wordpress-aws.md | 163 ++++++++++++++--- docs/workloads/azure/wordpress-azure.md | 140 +++++++++------ docs/workloads/gcp/wordpress-gcp.md | 167 ++++-------------- 9 files changed, 486 insertions(+), 364 deletions(-) rename cluster/examples/workloads/wordpress-aws/{kubernetes.yaml => cluster.yaml} (100%) diff --git a/cluster/examples/workloads/wordpress-aws/kubernetes.yaml b/cluster/examples/workloads/wordpress-aws/cluster.yaml similarity index 100% rename from cluster/examples/workloads/wordpress-aws/kubernetes.yaml rename to cluster/examples/workloads/wordpress-aws/cluster.yaml diff --git a/docs/README.md b/docs/README.md index 6503c34f6cb..ff7dc9d271e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,6 +12,8 @@ Crossplane includes a workload scheduler that can factor a number of criteria in For a deeper dive into Crossplane, see the [architecture](https://docs.google.com/document/d/1whncqdUeU2cATGEJhHvzXWC9xdK29Er45NJeoemxebo/edit?usp=sharing) document. +## Table of Contents + * [Quick Start Guide](quick-start.md) * [Getting Started](getting-started.md) * [Installing Crossplane](install-crossplane.md) diff --git a/docs/cloud-providers/aws/aws-provider.md b/docs/cloud-providers/aws/aws-provider.md index dfd89108fc5..4b5dfc2bdbf 100644 --- a/docs/cloud-providers/aws/aws-provider.md +++ b/docs/cloud-providers/aws/aws-provider.md @@ -1,12 +1,18 @@ -## Amazon Web Services (AWS) +# Adding Amazon Web Services (AWS) to Crossplane -The following instructions will help you configure AWS. +In this guide, we will walk through the steps necessary to configure your AWS account to be ready for integration with Crossplane. -### AWS Credentials +## AWS Credentials -AWS Credentials file +### Option 1: aws Command Line Tool + +If you have already installed and configured the [`aws` command line tool](https://aws.amazon.com/cli/), you can simply find your AWS credentials file in `~/.aws/credentials`. + +### Option 2: AWS Console in Web Browser + +If you do not have the `aws` tool installed, you can alternatively log into the [AWS console](https://aws.amazon.com/console/) and export the credentials. +The steps to follow below are from the [AWS SDK for GO](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html): -Follow the steps in the [AWS SDK for GO](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html) to get your access key ID and secret access key 1. Open the IAM console. 1. On the navigation menu, choose Users. 1. Choose your IAM user name (not the check box). @@ -14,100 +20,14 @@ Follow the steps in the [AWS SDK for GO](https://docs.aws.amazon.com/sdk-for-go/ 1. To see the new access key, choose Show. Your credentials resemble the following: - Access key ID: AKIAIOSFODNN7EXAMPLE - Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -1. To download the key pair, choose Download .csv file. Store the keys +1. To download the key pair, choose Download .csv file. + +Then convert the `*.csv` file to the below format and save it to `~/.aws/credentials`: -Convert *.csv to `.aws/credentials` format ``` [default] aws_access_key_id = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY ``` -**Note** If you have installed and configured `aws cli` you can find your AWS credentials file in `~/.aws/credentials` - -## Setup AWS provider - -Next, create a `example` namespace: - -```console -kubectl create namespace example -``` - -### Create credentials - -1. Get base64 encoded credentials with cat ~/.aws/credentials|base64|tr -d '\n' -1. Replace BASE64ENCODED_AWS_PROVIDER_CREDS in cluster/examples/workloads/wordpress-aws/provider.yaml with value from previous step. - -## Deploy EKS Cluster - -### Create a named keypair -* If you already have an ec2 keypair you can use your existing key pair https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html -* Replace your keypair name in cluster/examples/workloads/wordpress-aws/provider.yaml in EKS_WORKER_KEY_NAME - -### Create your Amazon EKS Service Role -[Original Source](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) - -1. Open the IAM console at https://console.aws.amazon.com/iam/. -1. Choose Roles, then Create role. -1. Choose EKS from the list of services, then Allows Amazon EKS to manage your clusters on your behalf for your use case, then Next: Permissions. -1. Choose Next: Review. -1. For Role name, enter a unique name for your role, such as eksServiceRole, then choose Create role. -1. Replace EKS_ROLE_ARN in cluster/examples/workloads/wordpress-aws/provider.yaml with role arn from previous step. - -### Create your Amazon EKS Cluster VPC -[Original Source](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) - -1. Open the AWS CloudFormation console at https://console.aws.amazon.com/cloudformation. -1. From the navigation bar, select a Region that supports Amazon EKS. - ```> Note - Amazon EKS is available in the following Regions at this time: - * US West (Oregon) (us-west-2) - * US East (N. Virginia) (us-east-1) - * EU (Ireland) (eu-west-1) - ``` - -1. Choose Create stack. -1. For Choose a template, select Specify an Amazon S3 template URL. -1. Paste the following URL into the text area and choose Next: - ``` - https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2018-11-07/amazon-eks-vpc-sample.yaml - ``` -1. On the Specify Details page, fill out the parameters accordingly, and then choose Next. - ``` - * Stack name: Choose a stack name for your AWS CloudFormation stack. For example, you can call it eks-vpc. - * VpcBlock: Choose a CIDR range for your VPC. You may leave the default value. - * Subnet01Block: Choose a CIDR range for subnet 1. You may leave the default value. - * Subnet02Block: Choose a CIDR range for subnet 2. You may leave the default value. - * Subnet03Block: Choose a CIDR range for subnet 3. You may leave the default value. - ``` -1. (Optional) On the Options page, tag your stack resources. Choose Next. -1. On the Review page, choose Create. -1. When your stack is created, select it in the console and choose Outputs. -1. Replace `EKS_VPC`, `EKS_ROLE_ARN`, `EKS_SUBNETS`, `EKS_SECURITY_GROUP` in cluster/examples/workloads/wordpress-aws/provider.yaml with values from previous step (vpcId, subnetIds, securityGroupIds). Note `EKS_SECURITY_GROUP` needs to be replaced twice in file. -1. Replace `REGION` in cluster/examples/workloads/wordpress-aws/provider.yaml with the region you selected in VPC creation. - -### Create an RDS subnet group -1. Navigate to aws console in same region as eks clsuter -1. Navigate to `RDS` service -1. Naviate to `Subnet groups` in left hand pane -1. Click `Create DB Subnet Group` -1. Name your subnet i.e. eks-db-subnets -1. Select the VPC created in the EKS VPC step -1. Click `Add all subnets related to this VPC` -1. Click Create -1. Replace `RDS_SUBNET_GROUP` in cluster/examples/workloads/wordpress-aws/provider.yaml in DBSubnetgroup name you just created. - -### Create an RDS Security Group (example only) - -**Note**: This will make your RDS instance visible from Anywhere on the internet. This if for **EXAMPLE PURPOSES ONLY**, and -is **NOT RECOMMENDED** for production system. - -1. Navigate to ec2 in the region of the EKS cluster -1. Navigate to security groups -1. Select the same VPC from the EKS cluster. -1. On the Inbound Rules tab, choose Edit. - - For Type, choose `MYSQL/Aurora` - - For Port Range, type `3306` - - For Source, choose `Anywhere` from drop down or type: `0.0.0.0/0` -1. Choose Add another rule if you need to add more IP addresses or different port ranges. -1. Replace `RDS_SECURITY_GROUP` in cluster/examples/workloads/wordpress-aws/provider.yaml with the security group we just created. \ No newline at end of file +After the steps above, you should have your AWS credentials stored in `~/.aws/credentials`. diff --git a/docs/cloud-providers/azure/azure-provider.md b/docs/cloud-providers/azure/azure-provider.md index 73ce747ab4a..24dc425e679 100644 --- a/docs/cloud-providers/azure/azure-provider.md +++ b/docs/cloud-providers/azure/azure-provider.md @@ -1,8 +1,13 @@ -## Microsoft Azure +# Adding Microsoft Azure to Crossplane -Azure service principal credentials are needed for an admin account, which must be created before starting this Wordpress Workload example. +In this guide, we will walk through the steps necessary to configure your Azure account to be ready for integration with Crossplane. +The general steps we will take are summarized below: -### Preparing your Microsoft Azure Account +* Create a new service principal (account) that Crossplane will use to create and manage Azure resources +* Add the required permissions to the account +* Consent to the permissions using an administrator account + +## Preparing your Microsoft Azure Account In order to manage resources in Azure, you must provide credentials for a Azure service principal that Crossplane can use to authenticate. This assumes that you have already [set up the Azure CLI client](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli?view=azure-cli-latest) with your credentials. @@ -14,13 +19,13 @@ Create a JSON file that contains all the information needed to connect and authe az ad sp create-for-rbac --sdk-auth --role Owner > crossplane-azure-provider-key.json ``` -Save the `clientID` value from the JSON file we just created to an environment variable: +Take note of the `clientID` value from the JSON file that we just created, and save it to an environment variable: ```console export AZURE_CLIENT_ID= ``` -Now add the required permissions to the service principal we created that allow us to manage the necessary resources in Azure: +Now add the required permissions to the service principal that will allow it to manage the necessary resources in Azure: ```console # add required Azure Active Directory permissions @@ -40,12 +45,17 @@ After these steps are completed, you should have the following file on your loca * `crossplane-azure-provider-key.json` -## Grant Consent to application -1. `echo ${AZURE_CLIENT_ID}` and note id -1. Navigate to azure console: https://portal.azure.com -1. Click Azure Active Directory +## Grant Consent to Application Permissions + +One more step is required to fully grant the permissions to the new service principal. +From the Azure Portal, you need to grant consent for the permissions using an admin account. +The steps to perform this action are listed below: + +1. `echo ${AZURE_CLIENT_ID}` and note this ID value +1. Navigate to the Azure Portal: https://portal.azure.com +1. Click `Azure Active Directory`, or find it in the `All services` list 1. Click `App registrations (Preview)` -1. Click on app item where client id matches step 1 +1. Click on the application from the list where the application (client) ID matches the value from step 1 1. Click `API permissions` 1. Click `Grant admin consent for Default Directory` 1. Click `Yes` diff --git a/docs/cloud-providers/gcp/gcp-provider.md b/docs/cloud-providers/gcp/gcp-provider.md index aec3339f3b1..8cca906dc31 100644 --- a/docs/cloud-providers/gcp/gcp-provider.md +++ b/docs/cloud-providers/gcp/gcp-provider.md @@ -1,49 +1,31 @@ -## Google Cloud Platform (GCP) +# Adding Google Cloud Platform (GCP) to Crossplane -Create a GCP example project which we will use to host our example GKE cluster, as well as our example CloudSQL instance. +In this guide, we will walk through the steps necessary to configure your GCP account to be ready for integration with Crossplane. +The general steps we will take are summarized below: -- Login into [GCP Console](https://console.cloud.google.com) -- Create a new project (either stand alone or under existing organization) -- Create Example Service Account - - Navigate to: [Create Service Account](https://console.cloud.google.com/iam-admin/serviceaccounts) - - `Service Account Name`: type "example" - - `Service Account ID`: leave auto assigned - - `Service Account Description`: type "Crossplane example" - - Hit `Create` button - - This should advance to the next section `2 Grant this service account to project (optional)` - - We will assign this account 3 roles: - - `Service Account User` - - `Cloud SQL Admin` - - `Kubernetes Engine Admin` - - Hit `Create` button - - This should advance to the next section `3 Grant users access to this service account (optinoal)` - - We don't need to assign any user or admin roles to this account for the example purposes, so you can leave following two fields blank: - - `Service account users role` - - `Service account admins role` - - Next, we will create and export service account key - - Hit `+ Create Key` button. - - This should open a `Create Key` side panel - - Select `json` for the Key type (should be selected by default) - - Hit `Create` - - This should show `Private key saved to your computer` confirmation dialog - - You also should see `crossplane-example-1234-[suffix].json` file in your browser's Download directory - - Save (copy or move) this file into example (this) directory, with new name `key.json` -- Enable `Cloud SQL API` - - Navigate to [Cloud SQL Admin API](https://console.developers.google.com/apis/api/sqladmin.googleapis.com/overview) - - Hit `Enable` -- Enable `Kubernetes Engine API` - - Navigate to [Kubernetes Engine API](https://console.developers.google.com/apis/api/container.googleapis.com/overview) - - Hit `Enable` +* Create a new example project that all resources will be deployed to +* Enable required APIs such as Kubernetes and CloudSQL +* Create a service account that will be used to perform GCP operations from Crossplane +* Assign necessary roles to the service account +* Enable billing + +For your convenience, the specific steps to accomplish those tasks are provided for you below using either the `gcloud` command line tool, or the GCP console in a web browser. +You can choose whichever you are more comfortable with. + +## Option 1: gcloud Command Line Tool -If you have `gcloud` utility, you can ran following commands from the example directory +If you have the `gcloud` tool installed, you can run below commands from the example directory. +It +Instructions for installing `gcloud` can be found in the [Google docs](https://cloud.google.com/sdk/install). ```bash -# list your organizations (if applicable) +# list your organizations (if applicable), take note of the specific organization ID you want to use +# if you have more than one organization (not common) gcloud organizations list - + # create a new project export EXAMPLE_PROJECT_NAME=crossplane-example-123 -gcloud projects create $EXAMPLE_PROJECT_NAME --enable-cloud-apis [--organization ORANIZATION_ID] +gcloud projects create $EXAMPLE_PROJECT_NAME --enable-cloud-apis [--organization ORGANIZATION_ID] # record the PROJECT_ID value of the newly created project export EXAMPLE_PROJECT_ID=$(gcloud projects list --filter NAME=$EXAMPLE_PROJECT_NAME --format="value(PROJECT_ID)") @@ -67,10 +49,51 @@ gcloud projects add-iam-policy-binding $EXAMPLE_PROJECT_ID --member "serviceAcco gcloud projects add-iam-policy-binding $EXAMPLE_PROJECT_ID --member "serviceAccount:$EXAMPLE_SA" --role="roles/container.admin" ``` -### Enable Billing -In order to create GKE clusters you must enable Billing. +## Option 2: GCP Console in a Web Browser + +If you chose to use the `gcloud` tool, you can skip this section entirely. + +Create a GCP example project which we will use to host our example GKE cluster, as well as our example CloudSQL instance. + +- Login into [GCP Console](https://console.cloud.google.com) +- Create a new project (either stand alone or under existing organization) +- Create Example Service Account + - Navigate to: [Create Service Account](https://console.cloud.google.com/iam-admin/serviceaccounts) + - `Service Account Name`: type "example" + - `Service Account ID`: leave auto assigned + - `Service Account Description`: type "Crossplane example" + - Click `Create` button + - This should advance to the next section `2 Grant this service account to project (optional)` + - We will assign this account 3 roles: + - `Service Account User` + - `Cloud SQL Admin` + - `Kubernetes Engine Admin` + - Click `Create` button + - This should advance to the next section `3 Grant users access to this service account (optional)` + - We don't need to assign any user or admin roles to this account for the example purposes, so you can leave following two fields blank: + - `Service account users role` + - `Service account admins role` + - Next, we will create and export service account key + - Click `+ Create Key` button. + - This should open a `Create Key` side panel + - Select `json` for the Key type (should be selected by default) + - Click `Create` + - This should show `Private key saved to your computer` confirmation dialog + - You also should see `crossplane-example-1234-[suffix].json` file in your browser's Download directory + - Save (copy or move) this file into example (this) directory, with new name `key.json` +- Enable `Cloud SQL API` + - Navigate to [Cloud SQL Admin API](https://console.developers.google.com/apis/api/sqladmin.googleapis.com/overview) + - Click `Enable` +- Enable `Kubernetes Engine API` + - Navigate to [Kubernetes Engine API](https://console.developers.google.com/apis/api/container.googleapis.com/overview) + - Click `Enable` + +## Enable Billing + +No matter what option you chose to configure the previous steps, you will need to enable billing for your account in order to create and use Kubernetes clusters with GKE. + - Go to [GCP Console](https://console.cloud.google.com) - Select example project - - Hit "Enable Billing" + - Click `Enable Billing` - Go to [Kubernetes Clusters](https://console.cloud.google.com/kubernetes/list) - - Hit "Enable Billing" \ No newline at end of file + - Click `Enable Billing` \ No newline at end of file diff --git a/docs/deploy.md b/docs/deploy.md index aa60cc06c61..060188cc207 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -6,6 +6,131 @@ indent: true --- # Deploying Workloads -* [Crossplane Workload on Google Cloud Platform (GCP)](workloads/gcp/wordpress-gcp.md) -* [Crossplane Workload on Microsoft Azure](workloads/azure/wordpress-azure.md) -* [Crossplane Workload on Amazon Web Services](workloads/aws/wordpress-aws.md) +## Guides + +This section will walk you through how to deploy workloads to various cloud provider environments in a highly portable way. +For detailed instructions on how to deploy workloads to your cloud provider of choice, please visit the following guides: + +* [Deploying a Workload on Google Cloud Platform (GCP)](workloads/gcp/wordpress-gcp.md) +* [Deploying a Workload on Microsoft Azure](workloads/azure/wordpress-azure.md) +* [Deploying a Workload on Amazon Web Services](workloads/aws/wordpress-aws.md) + +## Workload Overview + +A workload is a schedulable unit of work and contains a payload as well as defines its requirements for how the workload should run and what resources it will consume. +This helps Crossplane setup connectivity between the workload and resources, and make intelligent decisions about where and how to provision and manage the resources in their entirety. +Crossplane's scheduler is responsible for deploying the workload to a target cluster, which in this guide we will also be using Crossplane to deploy within your chosen cloud provider. + +This walkthrough also demonstrates Crossplane's concept of a clean "separation of concerns" between developers and administrators. +Developers define workloads without having to worry about implementation details, environment constraints, and policies. +Administrators can define environment specifics, and policies. +The separation of concern leads to a higher degree of reusability and reduces complexity. + +During this walkthrough, we will assume two separate identities: + +1. Administrator (cluster or cloud) - responsible for setting up credentials and defining resource classes +2. Application Owner (developer) - responsible for defining and deploying the application and its dependencies + +## Workload Example + +### Dependency Resource + +Let's take a closer look at a dependency resource that a workload will declare: + +```yaml +## WordPress MySQL Database Instance +apiVersion: storage.crossplane.io/v1alpha1 +kind: MySQLInstance +metadata: + name: demo + namespace: default +spec: + classReference: + name: standard-mysql + namespace: crossplane-system + engineVersion: "5.7" +``` + +This will request to create a `MySQLInstance` version 5.7, which will be fulfilled by the `standard-mysql` `ResourceClass`. +Note that the application developer is not aware of any further specifics when it comes to the `MySQLInstance` beyond their requested engine version. +This enables highly portable workloads, since the environment specific details of the database are defined by the administrator in a `ResourceClass`. + +### Workload + +Now let's look at the workload itself, which will reference the dependency resource from above, as well as other information such as the target cluster to deploy to. + +```yaml +## WordPress Workload +apiVersion: compute.crossplane.io/v1alpha1 +kind: Workload +metadata: + name: demo + namespace: default +spec: + resources: + - name: demo + secretName: demo + targetCluster: + name: demo-gke-cluster + namespace: crossplane-system + targetDeployment: + apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: wordpress + labels: + app: wordpress + spec: + selector: + app: wordpress + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + spec: + containers: + - name: wordpress + image: wordpress:4.6.1-apache + env: + - name: WORDPRESS_DB_HOST + valueFrom: + secretKeyRef: + name: demo + key: endpoint + - name: WORDPRESS_DB_USER + valueFrom: + secretKeyRef: + name: demo + key: username + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + name: demo + key: password + ports: + - containerPort: 80 + name: wordpress + targetNamespace: demo + targetService: + apiVersion: v1 + kind: Service + metadata: + name: wordpress + spec: + ports: + - port: 80 + selector: + app: wordpress + type: LoadBalancer +``` + +This `Workload` definition contains multiple components that informs Crossplane on how to deploy the workload and its resources: + +- Resources: list of the resources required by the payload application +- TargetCluster: the cluster where the payload application and all its requirements should be deployed +- TargetNamespace: the namespace on the target cluster +- Workload Payload: + - TargetDeployment + - TargetService diff --git a/docs/workloads/aws/wordpress-aws.md b/docs/workloads/aws/wordpress-aws.md index b8a7a156cdc..4da97bf854d 100644 --- a/docs/workloads/aws/wordpress-aws.md +++ b/docs/workloads/aws/wordpress-aws.md @@ -1,24 +1,129 @@ -# Wordpress on AWS - -## Deploy Wordpress Resources - -Now deploy all the Wordpress provider and workload resources, including the RDS database, and EKS cluster with the following single commands: - -Create provider +# Deploying a WordPress Workload on AWS + +This guide will walk you through how to use Crossplane to deploy a stateful workload in a portable way to AWS. +In this environment, the following components will be dynamically provisioned and configured during this guide: + +* EKS Kubernetes cluster +* RDS MySQL database +* WordPress application + +## Pre-requisites + +Before starting this guide, you should have already [configured your AWS account](../../cloud-providers/aws/aws-provider.md) for usage by Crossplane. + +You should have a `~/.aws/credentials` file on your local filesystem. + +## Administrator Tasks + +This section covers the tasks performed by the cluster or cloud administrator, which includes: + +- Import AWS provider credentials +- Define Resource classes for cluster and database resources +- Create all EKS pre-requisite artifacts +- Create a target EKS Kubernetes cluster (using dynamic provisioning with the cluster resource class) + +**Note**: all artifacts created by the administrator are stored/hosted in the `crossplane-system` namespace, which has +restricted access, i.e. `Application Owner(s)` should not have access to them. + +For the next steps, make sure your `kubectl` context points to the cluster where `Crossplane` was deployed. + +### Create credentials + +1. Get base64 encoded credentials with `cat ~/.aws/credentials|base64|tr -d '\n'` +1. Replace `BASE64ENCODED_AWS_PROVIDER_CREDS` in `cluster/examples/workloads/wordpress-aws/provider.yaml` with value from previous step. + +### Configure EKS Cluster Pre-requisites + +EKS cluster deployment is somewhat of an arduous process right now. +A number of artifacts and configuration needs to be set up within the AWS console first before proceeding with the provisioning of an EKS cluster using Crossplane. +We anticipate that AWS will make improvements on this user experience in the near future. + +#### Create a named keypair +* You can either reuse an existing ec2 key pair or create a new key pair with [these steps](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) +* Replace your key pair name in `cluster/examples/workloads/wordpress-aws/provider.yaml` in `EKS_WORKER_KEY_NAME` + +#### Create your Amazon EKS Service Role +[Original Source Guide](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) + +1. Open the [IAM console](https://console.aws.amazon.com/iam/). +1. Choose Roles, then Create role. +1. Choose EKS from the list of services, then Allows Amazon EKS to manage your clusters on your behalf for your use case, then Next: Permissions. +1. Choose Next: Review. +1. For Role name, enter a unique name for your role, such as eksServiceRole, then choose Create role. +1. Replace `EKS_ROLE_ARN` in `cluster/examples/workloads/wordpress-aws/provider.yaml` with role arn from previous step. + +#### Create your Amazon EKS Cluster VPC +[Original Source Guide](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) + +1. Open the [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation). +1. From the navigation bar, select a Region that supports Amazon EKS. + ```> Note + Amazon EKS is available in the following Regions at this time: + * US West (Oregon) (us-west-2) + * US East (N. Virginia) (us-east-1) + * EU (Ireland) (eu-west-1) + ``` + +1. Choose Create stack. +1. For Choose a template, select Specify an Amazon S3 template URL. +1. Paste the following URL into the text area and choose Next: + ``` + https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2018-11-07/amazon-eks-vpc-sample.yaml + ``` +1. On the Specify Details page, fill out the parameters accordingly, and then choose Next. + ``` + * Stack name: Choose a stack name for your AWS CloudFormation stack. For example, you can call it eks-vpc. + * VpcBlock: Choose a CIDR range for your VPC. You may leave the default value. + * Subnet01Block: Choose a CIDR range for subnet 1. You may leave the default value. + * Subnet02Block: Choose a CIDR range for subnet 2. You may leave the default value. + * Subnet03Block: Choose a CIDR range for subnet 3. You may leave the default value. + ``` +1. (Optional) On the Options page, tag your stack resources. Choose Next. +1. On the Review page, choose Create. +1. When your stack is created, select it in the console and choose Outputs. +1. Replace `EKS_VPC`, `EKS_ROLE_ARN`, `EKS_SUBNETS`, `EKS_SECURITY_GROUP` in `cluster/examples/workloads/wordpress-aws/provider.yaml` with values from previous step (vpcId, subnetIds, securityGroupIds). Note `EKS_SECURITY_GROUP` needs to be replaced twice in file. +1. Replace `REGION` in `cluster/examples/workloads/wordpress-aws/provider.yaml` with the region you selected in VPC creation. + +#### Create an RDS subnet group +1. Navigate to aws console in same region as the EKS clsuter +1. Navigate to `RDS` service +1. Navigate to `Subnet groups` in left hand pane +1. Click `Create DB Subnet Group` +1. Name your subnet i.e. `eks-db-subnets` +1. Select the VPC created in the EKS VPC step +1. Click `Add all subnets related to this VPC` +1. Click Create +1. Replace `RDS_SUBNET_GROUP` in `cluster/examples/workloads/wordpress-aws/provider.yaml` with the `DBSubnetgroup` name you just created. + +#### Create an RDS Security Group (example only) + +**Note**: This will make your RDS instance visible from Anywhere on the internet. +This if for **EXAMPLE PURPOSES ONLY**, and is **NOT RECOMMENDED** for production system. + +1. Navigate to ec2 in the region of the EKS cluster +1. Navigate to security groups +1. Select the same VPC from the EKS cluster. +1. On the Inbound Rules tab, choose Edit. + - For Type, choose `MYSQL/Aurora` + - For Port Range, type `3306` + - For Source, choose `Anywhere` from drop down or type: `0.0.0.0/0` +1. Choose Add another rule if you need to add more IP addresses or different port ranges. +1. Replace `RDS_SECURITY_GROUP` in `cluster/examples/workloads/wordpress-aws/provider.yaml` with the security group we just created. + +### Deploy all Workload Resources + +Now deploy all the workload resources, including the RDS database and EKS cluster with the following single commands: + +Create provider: ```console kubectl create -f cluster/examples/workloads/wordpress-aws/provider.yaml ``` -Create cluster +Create cluster: ```console kubectl create -f cluster/examples/workloads/wordpress-aws/cluster.yaml ``` - -Note: It will take about 10 minutes for the EKSCluster to become active, with about another 5 for the nodes to be started and join the cluster. - -## Waiting for load balancer and things to be available - It will take a while (~15 minutes) for the EKS cluster to be deployed and becoming ready. You can keep an eye on its status with the following command: @@ -26,34 +131,41 @@ You can keep an eye on its status with the following command: kubectl -n crossplane-system get ekscluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.location,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy ``` -Once the cluster is done provisioning, you should see output similar to the following (note the `STATE` field is `Succeeded` and the `ENDPOINT` field has a value): +Once the cluster is done provisioning, you should see output similar to the following (note the `STATE` field is `ACTIVE` and the `ENDPOINT` field has a value): ```console NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY eks-8f1f32c7-f6b4-11e8-844c-025000000001 ACTIVE https://B922855C944FC0567E9050FCD75B6AE5.yl4.us-west-2.eks.amazonaws.com standard-cluster Delete ``` -Now that the target EKS cluster is ready, we can deploy the Workload that contains all the Wordpress resources, including the SQL database, with the following single command: +## Application Developer Tasks + +This section covers the tasks performed by the application developer, which includes: + +- Define Workload in terms of Resources and Payload (Deployment/Service) which will be deployed into the target Kubernetes Cluster +- Define the dependency resource requirements, in this case a `MySQL` database + +Now that the EKS cluster is ready, let's begin deploying the workload as the application developer: ```console -kubectl -n demo create -f cluster/examples/workloads/wordpress-${provider}/workload.yaml +kubectl -n demo create -f cluster/examples/workloads/wordpress-aws/workload.yaml ``` -This will also take awhile to complete, since the MySQL database needs to be deployed before the Wordpress pod can consume it. +This will also take awhile to complete, since the MySQL database needs to be deployed before the WordPress pod can consume it. You can follow along with the MySQL database deployment with the following: ```console kubectl -n crossplane-system get rdsinstance -o custom-columns=NAME:.metadata.name,STATUS:.status.state,CLASS:.spec.classRef.name,VERSION:.spec.version ``` -Once the `STATUS` column is `Ready` like below, then the Wordpress pod should be able to connect to it: +Once the `STATUS` column is `available` like below, then the WordPress pod should be able to connect to it: ```console NAME STATUS CLASS VERSION mysql-2a0be04f-f748-11e8-844c-025000000001 available standard-mysql ``` -Now we can watch the Wordpress pod come online and a public IP address will get assigned to it: +Now we can watch the WordPress pod come online and a public IP address will get assigned to it: ```console kubectl -n demo get workload -o custom-columns=NAME:.metadata.name,CLUSTER:.spec.targetCluster.name,NAMESPACE:.spec.targetNamespace,DEPLOYMENT:.spec.targetDeployment.metadata.name,SERVICE-EXTERNAL-IP:.status.service.loadBalancer.ingress[0].ip @@ -66,13 +178,13 @@ NAME CLUSTER NAMESPACE DEPLOYMENT SERVICE-EXTERNAL-IP demo demo-cluster demo wordpress 104.43.240.15 ``` -Once Wordpress is running and has a public IP address through its service, we can get the URL with the following command: +Once WordPress is running and has a public IP address through its service, we can get the URL with the following command: ```console echo "http://$(kubectl get workload test-workload -o jsonpath='{.status.service.loadBalancer.ingress[0].ip}')" ``` -Paste that URL into your browser and you should see Wordpress running and ready for you to walk through the setup experience. You may need to wait a few minutes for this to become active in the aws elb. +Paste that URL into your browser and you should see WordPress running and ready for you to walk through the setup experience. You may need to wait a few minutes for this to become active in the AWS load balancer. ## Connect to your EKSCluster (optional) @@ -93,25 +205,24 @@ kubectl config use-context kubectl get nodes ``` - ## Clean-up -First delete the workload, which will delete Wordpress and the MySQL database: +First delete the workload, which will delete WordPress and the MySQL database: ```console -kubectl -n demo delete -f cluster/examples/workloads/wordpress-${provider}/workload.yaml +kubectl -n demo delete -f cluster/examples/workloads/wordpress-aws/workload.yaml ``` Then delete the EKS cluster: ```console -kubectl delete -f cluster/examples/workloads/wordpress-${provider}/cluster.yaml +kubectl delete -f cluster/examples/workloads/wordpress-aws/cluster.yaml ``` Finally, delete the provider credentials: ```console -kubectl delete -f cluster/examples/workloads/wordpress-${provider}/provider.yaml +kubectl delete -f cluster/examples/workloads/wordpress-aws/provider.yaml ``` > Note: There may still be an ELB that was not properly cleaned up, and you will need diff --git a/docs/workloads/azure/wordpress-azure.md b/docs/workloads/azure/wordpress-azure.md index 63d2e6b066a..482dc21faa1 100644 --- a/docs/workloads/azure/wordpress-azure.md +++ b/docs/workloads/azure/wordpress-azure.md @@ -1,84 +1,111 @@ -# WordPress Crossplane Workload on Microsoft Azure +# Deploying a WordPress Workload on Microsoft Azure -## Set environment variables +This guide will walk you through how to use Crossplane to deploy a stateful workload in a portable way to Azure. +In this environment, the following components will be dynamically provisioned and configured during this guide: -Set the following environment variables that will be used in this walkthrough: +* AKS Kubernetes cluster +* Azure MySQL database +* WordPress application -``` -export PROVIDER=AZURE -export provider=azure -export CLUSTER_TYPE=aksclusters -export DATABASE_TYPE=mysqlservers -``` +## Pre-requisites -## Deploy Wordpress Resources +Before starting this guide, you should have already [configured your Azure account](../../cloud-providers/azure/azure-provider.md) for usage by Crossplane. -Create the Azure provider object in your cluster: +You should have a `crossplane-azure-provider-key.json` file on your local filesystem, preferably at the root of where you cloned the [Crossplane repo](https://github.com/crossplaneio/crossplane). -```console -sed "s/BASE64ENCODED_${PROVIDER}_PROVIDER_CREDS/`cat crossplane-${provider}-provider-key.json|base64|tr -d '\n'`/g;" cluster/examples/workloads/wordpress-${provider}/provider.yaml | kubectl create -f - -``` +## Administrator Tasks -Next, create the AKS cluster that will eventually be the target cluster for your Workload deployment: +This section covers the tasks performed by the cluster or cloud administrator, which includes: -```console -kubectl create -f cluster/examples/workloads/wordpress-${provider}/cluster.yaml -``` +- Import Azure provider credentials +- Define Resource classes for cluster and database resources +- Create a target Kubernetes cluster (using dynamic provisioning with the cluster resource class) -It will take a while (~15 minutes) for the AKS cluster to be deployed and becoming ready. -You can keep an eye on its status with the following command: +**Note**: all artifacts created by the administrator are stored/hosted in the `crossplane-system` namespace, which has +restricted access, i.e. `Application Owner(s)` should not have access to them. -```console -kubectl -n crossplane-system get akscluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.location,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy -``` +For the next steps, make sure your `kubectl` context points to the cluster where `Crossplane` was deployed. -Once the cluster is done provisioning, you should see output similar to the following (note the `STATE` field is `Succeeded` and the `ENDPOINT` field has a value): +- Create the Azure provider object in your cluster: -```console -NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY -aks-587762b3-f72b-11e8-bcbe-0800278fedb1 Succeeded aks-587762b3-f72b-11e8-bcbe-080 crossplane-aks-653c32ef.hcp.centralus.azmk8s.io Central US standard-cluster Delete -``` + ```console + sed "s/BASE64ENCODED_AZURE_PROVIDER_CREDS/`cat crossplane-azure-provider-key.json|base64|tr -d '\n'`/g;" cluster/examples/workloads/wordpress-azure/provider.yaml | kubectl create -f - + ``` -Now that the target AKS cluster is ready, we can deploy the Workload that contains all the Wordpress resources, including the SQL database, with the following single command: +- Next, create the AKS cluster that will eventually be the target cluster for your Workload deployment: -```console -kubectl create -f cluster/examples/workloads/wordpress-${provider}/workload.yaml -``` + ```console + kubectl create -f cluster/examples/workloads/wordpress-${provider}/cluster.yaml + ``` -This will also take awhile to complete, since the MySQL database needs to be deployed before the Wordpress pod can consume it. -You can follow along with the MySQL database deployment with the following: + It will take a while (~15 minutes) for the AKS cluster to be deployed and becoming ready. You can keep an eye on its status with the following command: -```console -kubectl -n crossplane-system get mysqlserver -o custom-columns=NAME:.metadata.name,STATUS:.status.state,CLASS:.spec.classRef.name,VERSION:.spec.version -``` + ```console + kubectl -n crossplane-system get akscluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.location,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy + ``` -Once the `STATUS` column is `Ready` like below, then the Wordpress pod should be able to connect to it: + Once the cluster is done provisioning, you should see output similar to the following (note the `STATE` field is `Succeeded` and the `ENDPOINT` field has a value): -```console -NAME STATUS CLASS VERSION -mysql-58425bda-f72d-11e8-bcbe-0800278fedb1 Ready standard-mysql 5.7 -``` + ```console + NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY + aks-587762b3-f72b-11e8-bcbe-0800278fedb1 Succeeded aks-587762b3-f72b-11e8-bcbe-080 crossplane-aks-653c32ef.hcp.centralus.azmk8s.io Central US standard-cluster Delete + ``` -Now we can watch the Wordpress pod come online and a public IP address will get assigned to it: +To recap the operations that we just performed as the administrator: -```console -kubectl get workload -o custom-columns=NAME:.metadata.name,CLUSTER:.spec.targetCluster.name,NAMESPACE:.spec.targetNamespace,DEPLOYMENT:.spec.targetDeployment.metadata.name,SERVICE-EXTERNAL-IP:.status.service.loadBalancer.ingress[0].ip -``` +- Defined a `Provider` with Microsoft Azure service principal credentials +- Defined `ResourceClasses` for `KubernetesCluster` and `MySQLInstance` +- Provisioned (dynamically) an AKS Cluster using the `ResourceClass` -When a public IP address has been assigned, you'll see output similar to the following: +## Application Developer Tasks -```console -NAME CLUSTER NAMESPACE DEPLOYMENT SERVICE-EXTERNAL-IP -test-workload demo-cluster demo wordpress 104.43.240.15 -``` +This section covers the tasks performed by the application developer, which includes: -Once Wordpress is running and has a public IP address through its service, we can get the URL with the following command: +- Define Workload in terms of Resources and Payload (Deployment/Service) which will be deployed into the target Kubernetes Cluster +- Define the dependency resource requirements, in this case a `MySQL` database -```console -echo "http://$(kubectl get workload test-workload -o jsonpath='{.status.service.loadBalancer.ingress[0].ip}')" -``` +Let's begin deploying the workload as the application developer: + +- Now that the target AKS cluster is ready, we can deploy the Workload that contains all the Wordpress resources, including the SQL database, with the following single command: + + ```console + kubectl create -f cluster/examples/workloads/wordpress-${provider}/workload.yaml + ``` + + This will also take awhile to complete, since the MySQL database needs to be deployed before the Wordpress pod can consume it. + You can follow along with the MySQL database deployment with the following: + + ```console + kubectl -n crossplane-system get mysqlserver -o custom-columns=NAME:.metadata.name,STATUS:.status.state,CLASS:.spec.classRef.name,VERSION:.spec.version + ``` + + Once the `STATUS` column is `Ready` like below, then the Wordpress pod should be able to connect to it: + + ```console + NAME STATUS CLASS VERSION + mysql-58425bda-f72d-11e8-bcbe-0800278fedb1 Ready standard-mysql 5.7 + ``` + +- Now we can watch the Wordpress pod come online and a public IP address will get assigned to it: + + ```console + kubectl get workload -o custom-columns=NAME:.metadata.name,CLUSTER:.spec.targetCluster.name,NAMESPACE:.spec.targetNamespace,DEPLOYMENT:.spec.targetDeployment.metadata.name,SERVICE-EXTERNAL-IP:.status.service.loadBalancer.ingress[0].ip + ``` + + When a public IP address has been assigned, you'll see output similar to the following: + + ```console + NAME CLUSTER NAMESPACE DEPLOYMENT SERVICE-EXTERNAL-IP + test-workload demo-cluster demo wordpress 104.43.240.15 + ``` + +- Once Wordpress is running and has a public IP address through its service, we can get the URL with the following command: + + ```console + echo "http://$(kubectl get workload test-workload -o jsonpath='{.status.service.loadBalancer.ingress[0].ip}')" + ``` -Paste that URL into your browser and you should see Wordpress running and ready for you to walk through the setup experience. +- Paste that URL into your browser and you should see Wordpress running and ready for you to walk through the setup experience. ## Clean-up @@ -98,5 +125,4 @@ Finally, delete the provider credentials: ```console kubectl delete -f cluster/examples/workloads/wordpress-${provider}/provider.yaml -rm -fr crossplane-${provider}-* ``` \ No newline at end of file diff --git a/docs/workloads/gcp/wordpress-gcp.md b/docs/workloads/gcp/wordpress-gcp.md index 911072c6764..fc21aee23da 100644 --- a/docs/workloads/gcp/wordpress-gcp.md +++ b/docs/workloads/gcp/wordpress-gcp.md @@ -1,37 +1,30 @@ -# WordPress Crossplane Workload on GCP +# Deploying a WordPress Workload on GCP -Deploy WordPress application as a Workload into a dynamically provisioned Kubernetes cluster on GKE, -and backed by dynamically provisioned MySQL (CloudSQL) using Crossplane deployed on Minikube cluster +This guide will walk you through how to use Crossplane to deploy a stateful workload in a portable way to GCP. +In this environment, the following components will be dynamically provisioned and configured during this guide: -## GCP Setup +* GKE Kubernetes cluster +* CloudSQL database +* WordPress application -For this demo we must have a Google Cloud service account key in `json` format, which -corresponds to an active/valid GCP Service Account and has been granted the following roles: -- `Service Account User`: needed to have access to the service account information -- `Cloud SQL Admin`: needed to access (create/retrieve/connect/delete) CloudSQL instances -- `Kubernetes Engine User`: needed to access (create/connect/delete) GKE instances +## Pre-requisites -## WordPress Example -In the course of this demonstration we will show how to prepare and provision a sample application: WordPress which -uses MySQL backend database. +Before starting this guide, you should have already [configured your GCP account](../../cloud-providers/gcp/gcp-provider.md) for usage by Crossplane. -We will use local (`minikube`) Kubernetes cluster to host `Crossplane` (`Crossplane cluster`) +You should have a `key.json` file on your local filesystem, preferably at the root of where you cloned the [Crossplane repo](https://github.com/crossplaneio/crossplane). -To demonstrate `Crossplane` concept of `separation of concerns` during this demo we will assume two identities: -1. Administrator (cluster or cloud) - responsible for setting up credentials and defining resource classes -2. Application Owner (developer) - responsible for defining and deploying application and its dependencies +## Administrator Tasks -### As Administrator -you will perform following tasks: +This section covers the tasks performed by the cluster or cloud administrator, which includes: -- Create Cloud provider credentials -- Define Resource classes +- Import GCP provider credentials +- Define Resource classes for cluster and database resources - Create a target Kubernetes cluster (using dynamic provisioning with the cluster resource class) **Note**: all artifacts created by the administrator are stored/hosted in the `crossplane-system` namespace, which has -a restricted access, i.e. `Application Owner(s)` do not have access to them. +restricted access, i.e. `Application Owner(s)` should not have access to them. -For the next steps, make sure your `kubectl` context points to the `Crossplane` cluster +For the next steps, make sure your `kubectl` context points to the cluster where `Crossplane` was deployed. - Export Project ID @@ -45,7 +38,7 @@ For the next steps, make sure your `kubectl` context points to the `Crossplane` sed "s/BASE64ENCODED_CREDS/`cat key.json|base64 | tr -d '\n'`/g;s/DEMO_PROJECT_ID/$DEMO_PROJECT_ID/g" cluster/examples/workloads/wordpress-gcp/provider.yaml | kubectl create -f - ``` - - Verify that GCP Provider is in READY state + - Verify that GCP Provider is in `Ready` state ```bash kubectl -n crossplane-system get providers.gcp.crossplane.io -o custom-columns=NAME:.metadata.name,STATUS:.status.Conditions[0].Type,PROJECT-ID:.spec.projectID ``` @@ -61,13 +54,13 @@ For the next steps, make sure your `kubectl` context points to the `Crossplane` ``` Your output should be: ```bash - NAME PROVISIONER PROVIDER RECLAIM-POLICY - standard-cluster gkecluster.compute.gcp.crossplane.io/v1alpha1 gcp-provider Delete - standard-mysql cloudsqlinstance.database.gcp.crossplane.io/v1alpha1 gcp-provider Delete + NAME PROVISIONER PROVIDER RECLAIM-POLICY + standard-cluster gkecluster.compute.gcp.crossplane.io/v1alpha1 gcp-provider Delete + standard-mysql cloudsqlinstance.database.gcp.crossplane.io/v1alpha1 gcp-provider Delete ``` - Create a target Kubernetes cluster where `Application Owner(s)` will deploy their `WorkLoad(s)` - As administrator, you will create a Kubernetes cluster leveraging existing Kubernetes cluster `ResourceClass` and + As administrator, you will create a Kubernetes cluster leveraging the Kubernetes cluster `ResourceClass` that was created earlier and `Crossplane` Kubernetes cluster dynamic provisioning. ```bash kubectl apply -f cluster/examples/workloads/wordpress-gcp/kubernetes.yaml @@ -84,7 +77,7 @@ For the next steps, make sure your `kubectl` context points to the `Crossplane` demo-gke-cluster standard-cluster gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99 ``` - - Verify that Target GKE cluster was successfully created + - Verify that the target GKE cluster was successfully created ```bash kubectl -n crossplane-system get gkecluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.zone,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy ``` @@ -93,114 +86,22 @@ For the next steps, make sure your `kubectl` context points to the `Crossplane` ```bash NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99 RUNNING gke-6742fe8d-f5b3-11e8-9cec-9cb6d08bde99 146.148.93.40 us-central1-a standard-cluster Delete - ``` + ``` + +To recap the operations that we just performed as the administrator: -To recap, as administrator user, you have: - Defined a `Provider` with Google Service Account credentials -- Defined `ResourceClasses` for `KubernetesCluster` and `CloudSQLInstance` +- Defined `ResourceClasses` for `KubernetesCluster` and `MySQLInstance` - Provisioned (dynamically) a GKE Cluster using the `ResourceClass` -### As Application Owner -you will perform following tasks - -- Define Workload in terms of Resources and Payload (Deployment/Service) which will be deployed onto a Target Kubernetes Cluster -- Define dependency resource requirements, in this case `MySQL` database +## Application Developer Tasks -#### MySQL -First, let's take a look at the dependency resource -```yaml -## WordPress MySQL Database Instance -apiVersion: storage.crossplane.io/v1alpha1 -kind: MySQLInstance -metadata: - name: demo - namespace: default -spec: - classReference: - name: standard-mysql - namespace: crossplane-system - engineVersion: "5.7" -``` - -This will request to create a `MySQLInstance` version 5.7, which will be fulfilled by the `standard-mysql` ResourceClass. +This section covers the tasks performed by the application developer, which includes: -Note, the Application Owner is not aware of any further specifics when it comes down to `MySQLInstance` beyond the engine version. +- Define Workload in terms of Resources and Payload (Deployment/Service) which will be deployed into the target Kubernetes Cluster +- Define the dependency resource requirements, in this case a `MySQL` database -#### Workload -```yaml -## WordPress Workload -apiVersion: compute.crossplane.io/v1alpha1 -kind: Workload -metadata: - name: demo - namespace: default -spec: - resources: - - name: demo - secretName: demo - targetCluster: - name: demo-gke-cluster - namespace: crossplane-system - targetDeployment: - apiVersion: extensions/v1beta1 - kind: Deployment - metadata: - name: wordpress - labels: - app: wordpress - spec: - selector: - app: wordpress - strategy: - type: Recreate - template: - metadata: - labels: - app: wordpress - spec: - containers: - - name: wordpress - image: wordpress:4.6.1-apache - env: - - name: WORDPRESS_DB_HOST - valueFrom: - secretKeyRef: - name: demo - key: endpoint - - name: WORDPRESS_DB_USER - valueFrom: - secretKeyRef: - name: demo - key: username - - name: WORDPRESS_DB_PASSWORD - valueFrom: - secretKeyRef: - name: demo - key: password - ports: - - containerPort: 80 - name: wordpress - targetNamespace: demo - targetService: - apiVersion: v1 - kind: Service - metadata: - name: wordpress - spec: - ports: - - port: 80 - selector: - app: wordpress - type: LoadBalancer -``` - -The `Workload` definition spawns multiple constructs and kubernetes object. -- Resources: list of the resources required by the payload application. -- TargetCluster: the cluster where the payload application and all its requirements should be deployed. -- TargetNamespace: the namespace on the target cluster -- Workload Payload: - - TargetDeployment - - TargetService +Let's begin deploying the workload as the application developer: - Deploy workload ```bash @@ -242,9 +143,13 @@ The `Workload` definition spawns multiple constructs and kubernetes object. - Verify that `WordPress` service is accessible via `SERVICE-EXTERNAL-IP` by: - Navigate in your browser to `SERVICE-EXTERNAL-IP` - + +At this point, you should see the setup page for WordPress in your web browser. + ## Clean Up +Once you are done with this example, you can clean up all its artifacts with the following commands: + - Remove `Workload` ```bash kubectl delete -f cluster/examples/workloads/wordpress-gcp/workload.yaml @@ -255,7 +160,7 @@ kubectl delete -f cluster/examples/workloads/wordpress-gcp/workload.yaml kubectl delete -f cluster/examples/workloads/wordpress-gcp/kubernetes.yaml ``` -- Remove GCP Provider and ResourceClasses +- Remove GCP `Provider` and `ResourceClasses` ```bash kubectl delete -f cluster/examples/workloads/wordpress-gcp/provider.yaml ``` From 0fe0dca272eda814357713106ce85a02ca01cd87 Mon Sep 17 00:00:00 2001 From: Jared Watts Date: Tue, 4 Dec 2018 06:28:30 -0800 Subject: [PATCH 2/5] docs: concepts and terminology Signed-off-by: Jared Watts --- docs/concepts.md | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/docs/concepts.md b/docs/concepts.md index 404bfe05b20..7a0e4fa599a 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -7,12 +7,52 @@ weight: 410 ## Control Plane +Crossplane is an open source multicloud control plane that consists of smart controllers that can work across clouds to enable workload portability, provisioning and full-lifecycle management of infrastructure across a wide range of providers, vendors, regions, and offerings. +The control plane presents a declarative management style API that covers a wide range of portable abstractions that facilitate these goals across disparate environments, clusters, regions, and clouds. +Crossplane can be thought of as a higher-order orchestrator across cloud providers. +For convenience, Crossplane can run directly on-top of an existing Kubernetes cluster without requiring any changes, even though Crossplane does not necessarily schedule or run any containers on the host cluster. + ## Resources and Workloads +In Crossplane, a *resource* represents an external piece of infrastructure ranging from low level services like clusters and servers, to higher level infrastructure like databases, message queues, buckets, and more. +Resources are represented as persistent object within the crossplane, and they typically manage one or more pieces of external infrastructure within a cloud provider or cloud offering. +Resources can also represent local or in-cluster services. + +We model *workloads* as a schedulable units of work that the user intends to run on a cloud provider. +Crossplane will support multiple types of workloads including container and serverless. +You can think of workloads as units that run **your** code and applications. +Every type of workload has a different kind of payload. +For example, a container workload can include a set of objects that will be deployed on a managed Kubernetes cluster, or a reference to helm chart, etc. +A serverless workload could include a function that will run on a serverless managed service. +Workloads can contain requirements for where and how the workload can run, including regions, providers, affinity, cost, and others that the scheduler can use when assigning the workload. + + ## Resource Claims and Resource Classes +To support workload portability we expose the concept of a resource claim and a resource class. +A resource claim is a persistent object that captures the desired configuration of a resource from the perspective of a workload or application. +Its configuration is cloud-provider and cloud-offering independent and it’s free of implementation and/or environmental details. +A resource claim can be thought of as a request for an actual resource and is typically created by a developer or application owner. + +A resource class is configuration that contains implementation details specific to a certain environment or deployment, and policies related to a kind of resource. +A ResourceClass acts as a template with implementation details and policy for resources that will be dynamically provisioned by the workload at deployment time. +A resource class is typically created by an admin or infrastructure owner. + + ## Dynamic and Static Provisioning -## Consuming Connection Secrets +A resource can be statically or dynamically provisioned. +Static provisioning is when an administrator creates the resource manually. +They set the configuration required to provision and manage the corresponding external resource within a cloud provider or cloud offering. +Once provisioned, resources are available to be bound to resource claims. + +Dynamic provisioning is when an resource claim does not find a matching resource and provisions a new one instead. +The newly provisioned resource is automatically bound to the resource claim. +To enable dynamic provisioning the administrator needs to create one or more resource class objects. + +## Connection Secrets -## Terminology Guide \ No newline at end of file +Workloads reference all the resources the consume in their `resources` section. +This helps Crossplane setup connectivity between the workload and resource, and create objects that hold connection information. +For example, for a database provisioned and managed by Crossplane, a secret will be created that contains a connection string, user and password. +This secret will be propagated to the target cluster so that it can be used by the workload. From 5d6bfa0677b7b69099671f137cbf41774529cb1c Mon Sep 17 00:00:00 2001 From: Jared Watts Date: Tue, 4 Dec 2018 06:46:54 -0800 Subject: [PATCH 3/5] docs: running resources and contributing Signed-off-by: Jared Watts --- docs/contributing.md | 5 +++ docs/running-resources.md | 70 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/docs/contributing.md b/docs/contributing.md index fcf66f894df..4da16cca809 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -4,3 +4,8 @@ toc: true weight: 610 --- # Contributing + +Crossplane is a community driven project and we welcome contributions. +That includes [opening issues](https://github.com/crossplaneio/crossplane/issues) for improvements you'd like to see as well as submitting changes to the code base. + +For more information about the contribution process, please see the [contribution guide](https://github.com/crossplaneio/crossplane/blob/master/CONTRIBUTING.md). \ No newline at end of file diff --git a/docs/running-resources.md b/docs/running-resources.md index c3db4ce3a9f..766fec33f4e 100644 --- a/docs/running-resources.md +++ b/docs/running-resources.md @@ -11,8 +11,78 @@ A single Crossplane enables the provisioning and full-lifecycle management of in ## Running Databases +Database managed services can be statically or dynamically provisioned by Crossplane in AWS, GCP, and Azure. +An application developer simply has to specify their general need for a database such as MySQL, without any specific knowledge of what environment that database will run in or even what specific type of database it will be at runtime. +The following sample is all the application developer needs to specify in order to get the correct MySQL database (CloudSQL, RDS, Azure MySQL) provisioned and configured for their application: + +```yaml +apiVersion: storage.crossplane.io/v1alpha1 +kind: MySQLInstance +metadata: + name: demo-mysql +spec: + classReference: + name: standard-mysql + namespace: crossplane-system + engineVersion: "5.7" +``` + +The cluster administrator specifies a resource class that acts as a template with the implementation details and policy specific to the environment that the generic MySQL resource is being deployed to. +This enables the database to be dynamically provisioned at deployment time without the application developer needing to know any of the details, which promotes portability and reusability. +An example resource class that will provision a CloudSQL instance in GCP in order to fulfill the applications general MySQL requirement would look like this: + +```yaml +apiVersion: core.crossplane.io/v1alpha1 +kind: ResourceClass +metadata: + name: standard-mysql + namespace: crossplane-system +parameters: + tier: db-n1-standard-1 + region: us-west2 + storageType: PD_SSD +provisioner: cloudsqlinstance.database.gcp.crossplane.io/v1alpha1 +providerRef: + name: gcp-provider +reclaimPolicy: Delete +``` + ## Running Kubernetes Clusters +Kubernetes clusters are another type of resource that can be dynamically provisioned using a generic resource claim by the application developer and an environment specific resource class by the cluster administrator. + +Generic Kubernetes cluster resource claim created by the application developer: + +```yaml +apiVersion: compute.crossplane.io/v1alpha1 +kind: KubernetesCluster +metadata: + name: demo-cluster + namespace: crossplane-system +spec: + classReference: + name: standard-cluster + namespace: crossplane-system +``` + +Environment specific GKE cluster resource class created by the admin: + +```yaml +apiVersion: core.crossplane.io/v1alpha1 +kind: ResourceClass +metadata: + name: standard-cluster + namespace: crossplane-system +parameters: + machineType: n1-standard-1 + numNodes: "1" + zone: us-central1-a +provisioner: gkecluster.compute.gcp.crossplane.io/v1alpha1 +providerRef: + name: gcp-provider +reclaimPolicy: Delete +``` + ## Future support As the project continues to grow with support from the community, support for more resources will be added. From d8b1db2de379d798fb01f4f9407d963233115e27 Mon Sep 17 00:00:00 2001 From: Jared Watts Date: Tue, 4 Dec 2018 06:53:28 -0800 Subject: [PATCH 4/5] docs: reorder quickstart flow Signed-off-by: Jared Watts --- docs/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick-start.md b/docs/quick-start.md index a28cb2cdb8b..65e3bbf4b2d 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -12,6 +12,6 @@ The Workload will be deployed into the target Kubernetes cluster, and be configu The general steps for this example are as follows: -1. Set up a cloud provider and add it to Crossplane: [Adding a Cloud Provider](cloud-providers.md) 1. Install Crossplane so it is ready to manage resources on your behalf: [Install Crossplane](install-crossplane.md) +1. Set up a cloud provider and add it to Crossplane: [Adding a Cloud Provider](cloud-providers.md) 1. Deploy a portable workload to the cloud provider: [Deploying Workloads](deploy.md) From 35e797e098080ebe9564ae99b6d2a20120bd3802 Mon Sep 17 00:00:00 2001 From: Jared Watts Date: Tue, 4 Dec 2018 06:55:01 -0800 Subject: [PATCH 5/5] docs: remove old documentation Signed-off-by: Jared Watts --- docs-old/README.md | 5 - docs-old/architecture.md | 7 - docs-old/concepts.md | 6 - docs-old/contribute.md | 10 - docs-old/deploy.md | 11 - docs-old/design.md | 8 - docs-old/faqs.md | 6 - docs-old/guides.md | 6 - docs-old/prerequisites.md | 7 - docs-old/reference.md | 7 - docs-old/releases.md | 6 - docs-old/troubleshooting.md | 86 ------ docs-old/wordpress/quickstart-aws.md | 48 ---- docs-old/wordpress/quickstart-azure.md | 45 ---- docs-old/wordpress/quickstart-gcp.md | 47 ---- docs-old/wordpress/quickstart.md | 73 ----- docs-old/workload/aws/demo.md | 230 ---------------- docs-old/workload/azure/demo.md | 154 ----------- docs-old/workload/demo.md | 7 - docs-old/workload/gcp/demo.md | 357 ------------------------- 20 files changed, 1126 deletions(-) delete mode 100644 docs-old/README.md delete mode 100644 docs-old/architecture.md delete mode 100644 docs-old/concepts.md delete mode 100644 docs-old/contribute.md delete mode 100644 docs-old/deploy.md delete mode 100644 docs-old/design.md delete mode 100644 docs-old/faqs.md delete mode 100644 docs-old/guides.md delete mode 100644 docs-old/prerequisites.md delete mode 100644 docs-old/reference.md delete mode 100644 docs-old/releases.md delete mode 100644 docs-old/troubleshooting.md delete mode 100644 docs-old/wordpress/quickstart-aws.md delete mode 100644 docs-old/wordpress/quickstart-azure.md delete mode 100644 docs-old/wordpress/quickstart-gcp.md delete mode 100644 docs-old/wordpress/quickstart.md delete mode 100644 docs-old/workload/aws/demo.md delete mode 100644 docs-old/workload/azure/demo.md delete mode 100644 docs-old/workload/demo.md delete mode 100644 docs-old/workload/gcp/demo.md diff --git a/docs-old/README.md b/docs-old/README.md deleted file mode 100644 index b977f04b2bd..00000000000 --- a/docs-old/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# User Guides - -* [Wordpress Quickstart](wordpress/quickstart.md) -* [Wordpress Workload Demo](workload/demo.md) -* [Troubleshooting](troubleshooting.md) \ No newline at end of file diff --git a/docs-old/architecture.md b/docs-old/architecture.md deleted file mode 100644 index 19fb9f0bfa1..00000000000 --- a/docs-old/architecture.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Architecture -toc: true -weight: 310 -indent: true ---- -# Architecture diff --git a/docs-old/concepts.md b/docs-old/concepts.md deleted file mode 100644 index d2ebc983092..00000000000 --- a/docs-old/concepts.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Concepts -toc: true -weight: 300 ---- -# Concepts \ No newline at end of file diff --git a/docs-old/contribute.md b/docs-old/contribute.md deleted file mode 100644 index 85ffc6902a8..00000000000 --- a/docs-old/contribute.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Contribute -toc: true -weight: 170 ---- -# Contributing - -Thank you for your time and effort to help us improve Crossplane! Here are a few steps to get started. If you have any questions, don’t hesitate to reach out to us on our [Slack](https://crossplaneio.slack.com) dev channel. - -## Improving the docs \ No newline at end of file diff --git a/docs-old/deploy.md b/docs-old/deploy.md deleted file mode 100644 index c602e06b5e9..00000000000 --- a/docs-old/deploy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Deploy -toc: true -weight: 130 -indent: true ---- -# Deploy - -Thank you for your time and effort to help us improve Crossplane! Here are a few steps to get started. If you have any questions, don’t hesitate to reach out to us on our [Slack](https://crossplaneio.slack.com) dev channel. - -## Improving the docs \ No newline at end of file diff --git a/docs-old/design.md b/docs-old/design.md deleted file mode 100644 index 856ca17a2d7..00000000000 --- a/docs-old/design.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Design -toc: true -weight: 320 -indent: true ---- -# Design -* [Custom Secret Definitions](design/custom-secret-definitions.md) \ No newline at end of file diff --git a/docs-old/faqs.md b/docs-old/faqs.md deleted file mode 100644 index 1a0b1715fed..00000000000 --- a/docs-old/faqs.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: FAQS -toc: true -weight: 400 ---- -# FAQS \ No newline at end of file diff --git a/docs-old/guides.md b/docs-old/guides.md deleted file mode 100644 index a57c5aee8bf..00000000000 --- a/docs-old/guides.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Guides -toc: true -weight: 100 ---- -# Guides \ No newline at end of file diff --git a/docs-old/prerequisites.md b/docs-old/prerequisites.md deleted file mode 100644 index 19e910b7937..00000000000 --- a/docs-old/prerequisites.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Prerequisites -toc: true -weight: 120 ---- -# Prerequisites - diff --git a/docs-old/reference.md b/docs-old/reference.md deleted file mode 100644 index 04f053e197f..00000000000 --- a/docs-old/reference.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Reference -toc: true -weight: 200 ---- -# Reference - diff --git a/docs-old/releases.md b/docs-old/releases.md deleted file mode 100644 index 0f530bb6002..00000000000 --- a/docs-old/releases.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Releases -toc: true -weight: 500 ---- -# Releases \ No newline at end of file diff --git a/docs-old/troubleshooting.md b/docs-old/troubleshooting.md deleted file mode 100644 index 3d4646a3a53..00000000000 --- a/docs-old/troubleshooting.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Troubleshoot -toc: true -weight: 160 -indent: true ---- -# Troubleshooting - -## General Kubernetes debugging - -General help on debugging applications running in Kubernetes can be found in the [Troubleshoot Applications task doc](https://kubernetes.io/docs/tasks/debug-application-cluster/debug-application/). - -## Logs - -The first place to look for more details about any issue with Crossplane would be its logs: - -```console -kubectl -n crossplane-system logs -f $(kubectl -n crossplane-system get pod -l app=crossplane -o jsonpath='{.items[0].metadata.name}') -``` - -## Targeting Google Cloud Platform (GCP) - -Crossplane runs in any Kubernetes control plane and it is possible to target and manage environments external to the control plane it is running in. -In order to manage resources in GCP, you must provide credentials for a GCP service account that Crossplane can use to authenticate. -Normally, you don't need to create a brand new GCP key. -Instead, just obtain an existing key from a system administrator. - -### Configure gcloud - -Find the name of your desired GCP project and then set it as the `gcloud` default: - -```bash -gcloud config set project [your-project] -export PROJECT_ID=$(gcloud config get-value project) -``` - -### Create Service Account - -After configuring `gcloud`, the service account must be created, you can skip this step is you are reusing an existing account. - -```bash -# optional, skip this if the account has already been created -gcloud iam service-accounts create crossplane-gcp-provider --display-name "crossplane-gcp-provider" -``` - -### Create Service Account Key File - -Next create a local file called `crossplane-gcp-provider-key.json` with all the credentials information stored in it. - -```bash -gcloud iam service-accounts keys create crossplane-gcp-provider-key.json --iam-account crossplane-gcp-provider@${PROJECT_ID}.iam.gserviceaccount.com -``` - -### Bind Roles to Service Account - -Currently, Crossplane requires only one role for its operations, this list will continue to expand as support for new resources is added. - -* CloudSQL Admin: Full management of Cloud SQL instances and related objects. - -```bash -gcloud projects add-iam-policy-binding ${PROJECT_ID} --member "serviceAccount:crossplane-gcp-provider@${PROJECT_ID}.iam.gserviceaccount.com" --role "roles/cloudsql.admin" -``` - -### (Optional) GCP Service Account Secret - -If the example you are walking through does not create a Kubernetes secret, you can create one yourself now that you have obtained the service account JSON key file: - -```bash -# optional, skip if the example does this for you -kubectl -n crossplane-system create secret generic gcp-service-account-creds --from-file credentials.json=crossplane-gcp-provider-key.json -``` - -## GKE RBAC - -On GKE clusters, the default cluster role associated with your Google account does not have permissions to grant further RBAC permissions. -When running `make deploy`, you will see an error that contains a message similar to the following: - -```console -clusterroles.rbac.authorization.k8s.io "crossplane-manager-role" is forbidden: attempt to grant extra privileges -``` - -To work around this, you will you need to run a command **one time** that is **similar** to the following in order to bind your Google credentials `cluster-admin` role: - -```console -kubectl create clusterrolebinding dev-cluster-admin-binding --clusterrole=cluster-admin --user= -``` diff --git a/docs-old/wordpress/quickstart-aws.md b/docs-old/wordpress/quickstart-aws.md deleted file mode 100644 index 811987bdb35..00000000000 --- a/docs-old/wordpress/quickstart-aws.md +++ /dev/null @@ -1,48 +0,0 @@ -# Wordpress on AWS - -## Pre-requisites - -### AWS Credentials - -AWS Credentials file - -Follow the steps in the [AWS SDK for GO](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html) to get your access key ID and secret access key -1. Open the IAM console. -1. On the navigation menu, choose Users. -1. Choose your IAM user name (not the check box). -1. Open the Security credentials tab, and then choose Create access key. -1. To see the new access key, choose Show. Your credentials resemble the following: - - Access key ID: AKIAIOSFODNN7EXAMPLE - - Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -1. To download the key pair, choose Download .csv file. Store the keys - -Convert *.csv to `.aws/credentials` format -``` -[default] -aws_access_key_id = AKIAIOSFODNN7EXAMPLE -aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -``` - -**Note** If you have installed and configured `aws cli` you can find your AWS credentials file in `~/.aws/credentials` - -## Deploy Wordpress Resources - -Next, create a `demo` namespace: - -```console -kubectl create namespace demo -``` - -Deploy the AWS provider secret to your cluster: - -```console -sed "s/BASE64ENCODED_AWS_PROVIDER_CREDS/`cat ~/.aws/credentials|base64|tr -d '\n'`/g" cluster/examples/wordpress/aws/class/provider.yaml | kubectl create -f - -``` - -Now deploy all the Wordpress resources, including the RDS database, with the following single command: - -```console -kubectl -n demo create -f cluster/examples/wordpress/aws/class/wordpress.yaml -``` - -Now you can proceed back to the main quickstart to [wait for the resources to become ready](quickstart.md#waiting-for-completion). diff --git a/docs-old/wordpress/quickstart-azure.md b/docs-old/wordpress/quickstart-azure.md deleted file mode 100644 index 2a44322fd34..00000000000 --- a/docs-old/wordpress/quickstart-azure.md +++ /dev/null @@ -1,45 +0,0 @@ -# Wordpress on Microsoft Azure - -## Pre-requisites - -Azure service principal credentials are needed for an admin account, which must be created before starting this Wordpress example. - -| Description | Details | Required roles | -| ----- | --------- | ----------- | -| SQL admin | Service principal that can perform SQL admin operations such as creating a new database instance | `TODO` | - -Please refer to the [targeting Azure section](../../troubleshooting.md#targeting-microsoft-azure) for details on how to create this account with the required permissions from the table above. -After the account is created, you should have 1 file on your local filesystem: - -* `crossplane-azure-provider-key.json` - -## Set environment variables - -First, set the following environment variables that will be used in this walkthrough: - -``` -export PROVIDER=azure -export DATABASE_TYPE=mysqlservers -``` - -## Deploy Wordpress Resources - -Next, create a `demo` namespace: - -```console -kubectl create namespace demo -``` - -Deploy the Azure provider object to your cluster: - -```console -sed "s/BASE64ENCODED_AZURE_PROVIDER_CREDS/`cat crossplane-azure-provider-key.json|base64|tr -d '\n'`/g" cluster/examples/wordpress/azure/class/provider.yaml | kubectl create -f - -``` - -Now deploy all the Wordpress resources, including the SQL database, with the following single command: - -```console -kubectl -n demo create -f cluster/examples/wordpress/azure/class/wordpress.yaml -``` - -Now you can proceed back to the main quickstart to [wait for the resources to become ready](quickstart.md#waiting-for-completion). diff --git a/docs-old/wordpress/quickstart-gcp.md b/docs-old/wordpress/quickstart-gcp.md deleted file mode 100644 index 3e172c57fad..00000000000 --- a/docs-old/wordpress/quickstart-gcp.md +++ /dev/null @@ -1,47 +0,0 @@ -## Wordpress on Google Cloud Platform (GCP) - -### Pre-requisites - -Google service account credentials are needed for two separate accounts, these must be created before starting this Wordpress example. - -| Description | Details | Required roles | -| ----- | --------- | ----------- | -| SQL admin | Service account that can perform Cloud SQL admin operations such as creating a new database instance | `roles/cloudsql.admin` | -| SQL client | Service account that can connect to Cloud SQL databases and run SQL commands | `roles/cloudsql.client` | - -Please refer to the [targeting GCP section](../../troubleshooting.md#targeting-google-cloud-platform-gcp) for details on how to create these accounts with the required roles from the table above. -After the accounts are created, you should have two JSON key files on your local filesystem: - -* `crossplane-gcp-provider-key.json` -* `crossplane-gcp-sql-key.json` - -## Set environment variables - -First, set the following environment variables that will be used in this walkthrough: - -``` -export PROVIDER=gcp -export DATABASE_TYPE=cloudsqlinstances -``` - -### Deploy Wordpress Resources - -Next, create a `demo` namespace: - -```console -kubectl create namespace demo -``` - -Deploy the GCP provider object to your cluster: - -```console -sed "s/BASE64ENCODED_GCP_PROVIDER_CREDS/`cat crossplane-gcp-provider-key.json|base64|tr -d '\n'`/g" cluster/examples/wordpress/gcp/class/provider.yaml | kubectl create -f - -``` - -Now deploy all the Wordpress resources, including the Cloud SQL database, with the following single command: - -```console -sed "s/BASE64ENCODED_GCP_SQL_CREDS/`cat crossplane-gcp-sql-key.json|base64|tr -d '\n'`/g" cluster/examples/wordpress/gcp/class/wordpress.yaml | kubectl -n demo create -f - -``` - -Now you can proceed back to the main quickstart to [wait for the resources to become ready](quickstart.md#waiting-for-completion). diff --git a/docs-old/wordpress/quickstart.md b/docs-old/wordpress/quickstart.md deleted file mode 100644 index 4f764874140..00000000000 --- a/docs-old/wordpress/quickstart.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Quick Start Guides -toc: true -weight: 110 -indent: true ---- -# Crossplane Quickstart - -## Install Crossplane - -Install Crossplane in a GKE cluster first, for example with the following `helm` command after setting your preferred values for `image.repository` and `image.tag` in the `values.yaml` file: - -```bash -helm install --name crossplane --namespace crossplane-system ${GOPATH}/src/github.com/crossplaneio/crossplane/cluster/charts/crossplane -``` - -## Wordpress on AWS - -Follow the instructions in the [AWS quickstart](quickstart-aws.md) to start the process of running Wordpress on AWS - -## Wordpress on Google Cloud Platform (GCP) - -Follow the instructions in the [GCP quickstart](quickstart-gcp.md) to start the process of running Wordpress on Google Cloud Platform. - -## Wordpress on Microsoft Azure - -Follow the instructions in the [Azure quickstart](quickstart-azure.md) to start the process of running Wordpress on Microsoft Azure. - -## Waiting for Completion - -After finishing the specific instructions for your chosen cloud provider from the links above, we'll need to wait for the Wordpress pod to get to the `Running` status. Check on it with: - -```console -kubectl -n demo get pod -``` - -While the database is being deployed, you'll see the Wordpress pod in the `CreateContainerConfigError` status for awhile. -Follow along with the database deployment progress by watching the Crossplane logs: - -```console -kubectl -n crossplane-system logs -f $(kubectl -n crossplane-system get pod -l app=crossplane -o jsonpath='{.items[0].metadata.name}') -``` - -You can also watch the resources over time with the following watch command: -```console -watch -t -n1 "echo crossplane-system PODS && kubectl get pods -n crossplane-system -o wide && echo && \ - echo PODS && kubectl get pods -n demo -o wide && echo && \ - echo SERVICES && kubectl -n demo get svc -o wide && echo && \ - echo MYSQL CLAIMS && kubectl -n demo get mysqlinstance mysql-instance -o jsonpath='{.metadata.name}{\"\t\"}{.status.bindingPhase}{\"\t\"}{range .status.Conditions[*]}{.Type}{\"=\"}{.Status}{\"\t\"}{end}' && echo && echo &&\ - echo MYSQL INSTANCES && kubectl -n crossplane-system get ${DATABASE_TYPE} -o jsonpath='{range .items[*]}{.metadata.name}{\"\t\"}{.status.bindingPhase}{\"\t\"}{.status.state}{\"\t\"}{range .status.Conditions[*]}{.Type}{\"=\"}{.Status}{\"\t\"}{end}{end}' && echo && \ - echo && echo NODES && kubectl get nodes -o wide" -``` - -Once the Wordpress pod is in the `Running` status and the Wordpress service has a valid `EXTERNAL-IP`, we can move to the next section to connect to it. - -## Connecting to Wordpress - -Retrieve the full URL of the Wordpress instance with the following command (note that the service's load balancer may take a bit to become ready): - -```bash -echo http://$(kubectl -n demo get service wordpress -o jsonpath='{.status.loadBalancer.ingress[0].ip}') -``` - -Copy and paste the URL into a web browser and you should see the Wordpress setup page. - -## Cleanup & Teardown - -When you are finished with your Wordpress instance, you can delete the resources from your cluster with: - -```console -kubectl -n demo delete -f cluster/examples/wordpress/${PROVIDER}/wordpress.yaml -kubectl -n demo delete -f cluster/examples/wordpress/${PROVIDER}/provider.yaml -``` \ No newline at end of file diff --git a/docs-old/workload/aws/demo.md b/docs-old/workload/aws/demo.md deleted file mode 100644 index 736f3e33531..00000000000 --- a/docs-old/workload/aws/demo.md +++ /dev/null @@ -1,230 +0,0 @@ -# Wordpress on AWS - -## Pre-requisites - -### AWS Credentials - -AWS Credentials file - -Follow the steps in the [AWS SDK for GO](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html) to get your access key ID and secret access key -1. Open the IAM console. -1. On the navigation menu, choose Users. -1. Choose your IAM user name (not the check box). -1. Open the Security credentials tab, and then choose Create access key. -1. To see the new access key, choose Show. Your credentials resemble the following: - - Access key ID: AKIAIOSFODNN7EXAMPLE - - Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -1. To download the key pair, choose Download .csv file. Store the keys - -Convert *.csv to `.aws/credentials` format -``` -[default] -aws_access_key_id = AKIAIOSFODNN7EXAMPLE -aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -``` - -**Note** If you have installed and configured `aws cli` you can find your AWS credentials file in `~/.aws/credentials` - -## Setup AWS provider - -Next, create a `demo` namespace: - -```console -kubectl create namespace demo -``` - -### Create credentials - -1. Get base64 encoded credentials with cat ~/.aws/credentials|base64|tr -d '\n' -1. Replace BASE64ENCODED_AWS_PROVIDER_CREDS in cluster/examples/workloads/wordpress-aws/provider.yaml with value from previous step. - -## Deploy EKS Cluster - -### Create a named keypair -* If you already have an ec2 keypair you can use your existing key pair https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html -* Replace your keypair name in cluster/examples/workloads/wordpress-aws/provider.yaml in EKS_WORKER_KEY_NAME - -### Create your Amazon EKS Service Role -[Original Source](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) - -1. Open the IAM console at https://console.aws.amazon.com/iam/. -1. Choose Roles, then Create role. -1. Choose EKS from the list of services, then Allows Amazon EKS to manage your clusters on your behalf for your use case, then Next: Permissions. -1. Choose Next: Review. -1. For Role name, enter a unique name for your role, such as eksServiceRole, then choose Create role. -1. Replace EKS_ROLE_ARN in cluster/examples/workloads/wordpress-aws/provider.yaml with role arn from previous step. - -### Create your Amazon EKS Cluster VPC -[Original Source](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) - -1. Open the AWS CloudFormation console at https://console.aws.amazon.com/cloudformation. -1. From the navigation bar, select a Region that supports Amazon EKS. - ```> Note - Amazon EKS is available in the following Regions at this time: - * US West (Oregon) (us-west-2) - * US East (N. Virginia) (us-east-1) - * EU (Ireland) (eu-west-1) - ``` - -1. Choose Create stack. -1. For Choose a template, select Specify an Amazon S3 template URL. -1. Paste the following URL into the text area and choose Next: - ``` - https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2018-11-07/amazon-eks-vpc-sample.yaml - ``` -1. On the Specify Details page, fill out the parameters accordingly, and then choose Next. - ``` - * Stack name: Choose a stack name for your AWS CloudFormation stack. For example, you can call it eks-vpc. - * VpcBlock: Choose a CIDR range for your VPC. You may leave the default value. - * Subnet01Block: Choose a CIDR range for subnet 1. You may leave the default value. - * Subnet02Block: Choose a CIDR range for subnet 2. You may leave the default value. - * Subnet03Block: Choose a CIDR range for subnet 3. You may leave the default value. - ``` -1. (Optional) On the Options page, tag your stack resources. Choose Next. -1. On the Review page, choose Create. -1. When your stack is created, select it in the console and choose Outputs. -1. Replace `EKS_VPC`, `EKS_ROLE_ARN`, `EKS_SUBNETS`, `EKS_SECURITY_GROUP` in cluster/examples/workloads/wordpress-aws/provider.yaml with values from previous step (vpcId, subnetIds, securityGroupIds). Note `EKS_SECURITY_GROUP` needs to be replaced twice in file. -1. Replace `REGION` in cluster/examples/workloads/wordpress-aws/provider.yaml with the region you selected in VPC creation. - -### Create an RDS subnet group -1. Navigate to aws console in same region as eks clsuter -1. Navigate to `RDS` service -1. Naviate to `Subnet groups` in left hand pane -1. Click `Create DB Subnet Group` -1. Name your subnet i.e. eks-db-subnets -1. Select the VPC created in the EKS VPC step -1. Click `Add all subnets related to this VPC` -1. Click Create -1. Replace `RDS_SUBNET_GROUP` in cluster/examples/workloads/wordpress-aws/provider.yaml in DBSubnetgroup name you just created. - -### Create an RDS Security Group (demo only) - -**Note**: This will make your RDS instance visible from Anywhere on the internet. This if for **DEMO PURPOSES ONLY**, and -is **NOT RECOMMENDED** for production system. - -1. Navigate to ec2 in the region of the EKS cluster -1. Navigate to security groups -1. Select the same VPC from the EKS cluster. -1. On the Inbound Rules tab, choose Edit. - - For Type, choose `MYSQL/Aurora` - - For Port Range, type `3306` - - For Source, choose `Anywhere` from drop down or type: `0.0.0.0/0` -1. Choose Add another rule if you need to add more IP addresses or different port ranges. -1. Replace `RDS_SECURITY_GROUP` in cluster/examples/workloads/wordpress-aws/provider.yaml with the security group we just created. - -## Deploy Wordpress Resources - -Now deploy all the Wordpress provider and workload resources, including the RDS database, and EKS cluster with the following single commands: - -Create provider -```console -kubectl create -f cluster/examples/workloads/wordpress-aws/provider.yaml -``` - -Create cluster -```console -kubectl create -f cluster/examples/workloads/wordpress-aws/cluster.yaml -``` - - -Note: It will take about 10 minutes for the EKSCluster to become active, with about another 5 for the nodes to be started and join the cluster. - -## Waiting for load balancer and things to be available - -It will take a while (~15 minutes) for the EKS cluster to be deployed and becoming ready. -You can keep an eye on its status with the following command: - -```console -kubectl -n crossplane-system get ekscluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.location,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy -``` - -Once the cluster is done provisioning, you should see output similar to the following (note the `STATE` field is `Succeeded` and the `ENDPOINT` field has a value): - -```console -NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY -eks-8f1f32c7-f6b4-11e8-844c-025000000001 ACTIVE https://B922855C944FC0567E9050FCD75B6AE5.yl4.us-west-2.eks.amazonaws.com standard-cluster Delete -``` - -Now that the target EKS cluster is ready, we can deploy the Workload that contains all the Wordpress resources, including the SQL database, with the following single command: - -```console -kubectl -n demo create -f cluster/examples/workloads/wordpress-${provider}/workload.yaml -``` - -This will also take awhile to complete, since the MySQL database needs to be deployed before the Wordpress pod can consume it. -You can follow along with the MySQL database deployment with the following: - -```console -kubectl -n crossplane-system get rdsinstance -o custom-columns=NAME:.metadata.name,STATUS:.status.state,CLASS:.spec.classRef.name,VERSION:.spec.version -``` - -Once the `STATUS` column is `Ready` like below, then the Wordpress pod should be able to connect to it: - -```console -NAME STATUS CLASS VERSION -mysql-2a0be04f-f748-11e8-844c-025000000001 available standard-mysql -``` - -Now we can watch the Wordpress pod come online and a public IP address will get assigned to it: - -```console -kubectl -n demo get workload -o custom-columns=NAME:.metadata.name,CLUSTER:.spec.targetCluster.name,NAMESPACE:.spec.targetNamespace,DEPLOYMENT:.spec.targetDeployment.metadata.name,SERVICE-EXTERNAL-IP:.status.service.loadBalancer.ingress[0].ip -``` - -When a public IP address has been assigned, you'll see output similar to the following: - -```console -NAME CLUSTER NAMESPACE DEPLOYMENT SERVICE-EXTERNAL-IP -demo demo-cluster demo wordpress 104.43.240.15 -``` - -Once Wordpress is running and has a public IP address through its service, we can get the URL with the following command: - -```console -echo "http://$(kubectl get workload test-workload -o jsonpath='{.status.service.loadBalancer.ingress[0].ip}')" -``` - -Paste that URL into your browser and you should see Wordpress running and ready for you to walk through the setup experience. You may need to wait a few minutes for this to become active in the aws elb. - -## Connect to your EKSCluster (optional) - -Requires: - * awscli - * aws-iam-authenticator - -Please see [Install instructions](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) section: `Install and Configure kubectl for Amazon EKS` - -When the EKSCluster is up and running, you can update your kubeconfig with: -```console -aws eks update-kubeconfig --name -``` - -Node pool is created after the master is up, so expect a few more minutes to wait, but eventually you can see that nodes joined with: -```console -kubectl config use-context -kubectl get nodes -``` - - -## Clean-up - -First delete the workload, which will delete Wordpress and the MySQL database: - -```console -kubectl -n demo delete -f cluster/examples/workloads/wordpress-${provider}/workload.yaml -``` - -Then delete the EKS cluster: - -```console -kubectl delete -f cluster/examples/workloads/wordpress-${provider}/cluster.yaml -``` - -Finally, delete the provider credentials: - -```console -kubectl delete -f cluster/examples/workloads/wordpress-${provider}/provider.yaml -``` - -> Note: There may still be an ELB that was not properly cleaned up, and you will need -to go to EC2 > ELBs and delete it manually. diff --git a/docs-old/workload/azure/demo.md b/docs-old/workload/azure/demo.md deleted file mode 100644 index 1936da92abf..00000000000 --- a/docs-old/workload/azure/demo.md +++ /dev/null @@ -1,154 +0,0 @@ -# WordPress Crossplane Workload on Microsoft Azure - -## Pre-requisites - -Azure service principal credentials are needed for an admin account, which must be created before starting this Wordpress Workload example. - -### Preparing your Microsoft Azure Account - -In order to manage resources in Azure, you must provide credentials for a Azure service principal that Crossplane can use to authenticate. -This assumes that you have already [set up the Azure CLI client](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli?view=azure-cli-latest) with your credentials. - -Create a JSON file that contains all the information needed to connect and authenticate to Azure: - -```console -# create service principal with Owner role -az ad sp create-for-rbac --sdk-auth --role Owner > crossplane-azure-provider-key.json -``` - -Save the `clientID` value from the JSON file we just created to an environment variable: - -```console -export AZURE_CLIENT_ID= -``` - -Now add the required permissions to the service principal we created that allow us to manage the necessary resources in Azure: - -```console -# add required Azure Active Directory permissions -az ad app permission add --id ${AZURE_CLIENT_ID} --api 00000002-0000-0000-c000-000000000000 --api-permissions 1cda74f2-2616-4834-b122-5cb1b07f8a59=Role 78c8a3c8-a07e-4b9e-af1b-b5ccab50a175=Role - -# grant (activate) the permissions -az ad app permission grant --id ${AZURE_CLIENT_ID} --api 00000002-0000-0000-c000-000000000000 --expires never -``` - -You might see an error similar to the following, but that is OK, the permissions should have gone through still: - -```console -Operation failed with status: 'Conflict'. Details: 409 Client Error: Conflict for url: https://graph.windows.net/e7985bc4-a3b3-4f37-b9d2-fa256023b1ae/oauth2PermissionGrants?api-version=1.6 -``` - -After these steps are completed, you should have the following file on your local filesystem: - -* `crossplane-azure-provider-key.json` - -## Grant Consent to application -1. `echo ${AZURE_CLIENT_ID}` and note id -1. Navigate to azure console: https://portal.azure.com -1. Click Azure Active Directory -1. Click `App registrations (Preview)` -1. Click on app item where client id matches step 1 -1. Click `API permissions` -1. Click `Grant admin consent for Default Directory` -1. Click `Yes` - -## Set environment variables - -Set the following environment variables that will be used in this walkthrough: - -``` -export PROVIDER=AZURE -export provider=azure -export CLUSTER_TYPE=aksclusters -export DATABASE_TYPE=mysqlservers -``` - -## Deploy Wordpress Resources - -Create the Azure provider object in your cluster: - -```console -sed "s/BASE64ENCODED_${PROVIDER}_PROVIDER_CREDS/`cat crossplane-${provider}-provider-key.json|base64|tr -d '\n'`/g;" cluster/examples/workloads/wordpress-${provider}/provider.yaml | kubectl create -f - -``` - -Next, create the AKS cluster that will eventually be the target cluster for your Workload deployment: - -```console -kubectl create -f cluster/examples/workloads/wordpress-${provider}/cluster.yaml -``` - -It will take a while (~15 minutes) for the AKS cluster to be deployed and becoming ready. -You can keep an eye on its status with the following command: - -```console -kubectl -n crossplane-system get akscluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.location,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy -``` - -Once the cluster is done provisioning, you should see output similar to the following (note the `STATE` field is `Succeeded` and the `ENDPOINT` field has a value): - -```console -NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY -aks-587762b3-f72b-11e8-bcbe-0800278fedb1 Succeeded aks-587762b3-f72b-11e8-bcbe-080 crossplane-aks-653c32ef.hcp.centralus.azmk8s.io Central US standard-cluster Delete -``` - -Now that the target AKS cluster is ready, we can deploy the Workload that contains all the Wordpress resources, including the SQL database, with the following single command: - -```console -kubectl create -f cluster/examples/workloads/wordpress-${provider}/workload.yaml -``` - -This will also take awhile to complete, since the MySQL database needs to be deployed before the Wordpress pod can consume it. -You can follow along with the MySQL database deployment with the following: - -```console -kubectl -n crossplane-system get mysqlserver -o custom-columns=NAME:.metadata.name,STATUS:.status.state,CLASS:.spec.classRef.name,VERSION:.spec.version -``` - -Once the `STATUS` column is `Ready` like below, then the Wordpress pod should be able to connect to it: - -```console -NAME STATUS CLASS VERSION -mysql-58425bda-f72d-11e8-bcbe-0800278fedb1 Ready standard-mysql 5.7 -``` - -Now we can watch the Wordpress pod come online and a public IP address will get assigned to it: - -```console -kubectl get workload -o custom-columns=NAME:.metadata.name,CLUSTER:.spec.targetCluster.name,NAMESPACE:.spec.targetNamespace,DEPLOYMENT:.spec.targetDeployment.metadata.name,SERVICE-EXTERNAL-IP:.status.service.loadBalancer.ingress[0].ip -``` - -When a public IP address has been assigned, you'll see output similar to the following: - -```console -NAME CLUSTER NAMESPACE DEPLOYMENT SERVICE-EXTERNAL-IP -test-workload demo-cluster demo wordpress 104.43.240.15 -``` - -Once Wordpress is running and has a public IP address through its service, we can get the URL with the following command: - -```console -echo "http://$(kubectl get workload test-workload -o jsonpath='{.status.service.loadBalancer.ingress[0].ip}')" -``` - -Paste that URL into your browser and you should see Wordpress running and ready for you to walk through the setup experience. - -## Clean-up - -First delete the workload, which will delete Wordpress and the MySQL database: - -```console -kubectl delete -f cluster/examples/workloads/wordpress-${provider}/workload.yaml -``` - -Then delete the AKS cluster: - -```console -kubectl delete -f cluster/examples/workloads/wordpress-${provider}/cluster.yaml -``` - -Finally, delete the provider credentials: - -```console -kubectl delete -f cluster/examples/workloads/wordpress-${provider}/provider.yaml -rm -fr crossplane-${provider}-* -``` \ No newline at end of file diff --git a/docs-old/workload/demo.md b/docs-old/workload/demo.md deleted file mode 100644 index f3009acb524..00000000000 --- a/docs-old/workload/demo.md +++ /dev/null @@ -1,7 +0,0 @@ -# WordPress Demo - -Deploy WordPress application as a Workload into a dynamically provisioned Kubernetes clusters on GKE, -and backed by dynamically provisioned MySQL using Crossplane deployed on Minikube cluster - -* [WordPress Workload on Google Cloud Platform (GCP)](gcp/demo.md) -* [WordPress Workload on Microsoft Azure](azure/demo.md) diff --git a/docs-old/workload/gcp/demo.md b/docs-old/workload/gcp/demo.md deleted file mode 100644 index 7ca16b468b6..00000000000 --- a/docs-old/workload/gcp/demo.md +++ /dev/null @@ -1,357 +0,0 @@ -# WordPress Crossplane Workload on GCP - -Deploy WordPress application as a Workload into a dynamically provisioned Kubernetes cluster on GKE, -and backed by dynamically provisioned MySQL (CloudSQL) using Crossplane deployed on Minikube cluster - -## Requirements -- Minikube `v0.29.0+` -- A GCP account with administrator (or owner) level privileges. -- (Optional) `gcloud` command-line tool - -## Install Crossplane - -Install Crossplane in a Minikube cluster first, for example with the following `helm` command after setting your preferred values for `image.repository` and `image.tag` in the `values.yaml` file: - -```bash -helm install --name crossplane --namespace crossplane-system ${GOPATH}/src/github.com/crossplaneio/crossplane/cluster/charts/crossplane -``` - -## GCP Setup -Per requirements section, for this demo we must have a Google Cloud service account key in `json` format, which -corresponds to an active/valid GCP Service Account and has been granted the following roles: -- `Service Account User`: needed to have access to the service account information -- `Cloud SQL Admin`: needed to access (create/retrieve/connect/delete) CloudSQL instances -- `Kubernetes Engine User`: needed to access (create/connect/delete) GKE instances - -Create a GCP demo project which we will use to host our demo GKE cluster, as well as, our demo CloudSQL instance. - -- Login into [GCP Console](https://console.cloud.google.com) -- Create a new project (either stand alone or under existing organization) -- Create Demo Service Account - - Navigate to: [Create Service Account](https://console.cloud.google.com/iam-admin/serviceaccounts) - - `Service Account Name`: type "demo" - - `Service Account ID`: leave auto assigned - - `Service Account Description`: type "Crossplane demo" - - Hit `Create` button - - This should advance to the next section `2 Grant this service account to project (optional)` - - We will assign this account 3 roles: - - `Service Account User` - - `Cloud SQL Admin` - - `Kubernetes Engine Admin` - - Hit `Create` button - - This should advance to the next section `3 Grant users access to this service account (optinoal)` - - We don't need to assign any user or admin roles to this account for the demo purposes, so you can leave following two fields blank: - - `Service account users role` - - `Service account admins role` - - Next, we will create and export service account key - - Hit `+ Create Key` button. - - This should open a `Create Key` side panel - - Select `json` for the Key type (should be selected by default) - - Hit `Create` - - This should show `Private key saved to your computer` confirmation dialog - - You also should see `crossplane-demo-1234-[suffix].json` file in your browser's Download directory - - Save (copy or move) this file into demo (this) directory, with new name `key.json` -- Enable `Cloud SQL API` - - Navigate to [Cloud SQL Admin API](https://console.developers.google.com/apis/api/sqladmin.googleapis.com/overview) - - Hit `Enable` -- Enable `Kubernetes Engine API` - - Navigate to [Kubernetes Engine API](https://console.developers.google.com/apis/api/container.googleapis.com/overview) - - Hit `Enable` - -If you have `gcloud` utility, you can ran following commands from the demo directory - -```bash -# list your organizations (if applicable) -gcloud organizations list - -# create a new project -export DEMO_PROJECT_NAME=crossplane-demo-123 -gcloud projects create $DEMO_PROJECT_NAME --enable-cloud-apis [--organization ORANIZATION_ID] - -# record the PROJECT_ID value of the newly created project -export DEMO_PROJECT_ID=$(gcloud projects list --filter NAME=$DEMO_PROJECT_NAME --format="value(PROJECT_ID)") - -# enable Kubernetes API -gcloud --project $DEMO_PROJECT_ID services enable container.googleapis.com -# enable CloudSQL API -gcloud --project $DEMO_PROJECT_ID services enable sqladmin.googleapis.com - -# create service account -gcloud --project $DEMO_PROJECT_ID iam service-accounts create demo-123 --display-name "Crossplane Demo" -# export service account email -export DEMO_SA="demo-123@$DEMO_PROJECT_ID.iam.gserviceaccount.com" - -# create service account key (this will create a `key.json` file in your current working directory) -gcloud --project $DEMO_PROJECT_ID iam service-accounts keys create --iam-account $DEMO_SA key.json - -# assign roles -gcloud projects add-iam-policy-binding $DEMO_PROJECT_ID --member "serviceAccount:$DEMO_SA" --role="roles/iam.serviceAccountUser" -gcloud projects add-iam-policy-binding $DEMO_PROJECT_ID --member "serviceAccount:$DEMO_SA" --role="roles/cloudsql.admin" -gcloud projects add-iam-policy-binding $DEMO_PROJECT_ID --member "serviceAccount:$DEMO_SA" --role="roles/container.admin" -``` - -### Enable Billing -In order to create GKE clusters you must enable Billing. -- Go to [GCP Console](https://console.cloud.google.com) - - Select demo project - - Hit "Enable Billing" -- Go to [Kubernetes Clusters](https://console.cloud.google.com/kubernetes/list) - - Hit "Enable Billing" - -## WordPress Example -In the course of this demonstration we will show how to prepare and provision a sample application: WordPress which -uses MySQL backend database. - -We will use local (`minikube`) Kubernetes cluster to host `Crossplane` (`Crossplane cluster`) - -To demonstrate `Crossplane` concept of `separation of concerns` during this demo we will assume two identities: -1. Administrator (cluster or cloud) - responsible for setting up credentials and defining resource classes -2. Application Owner (developer) - responsible for defining and deploying application and its dependencies - -### As Administrator -you will perform following tasks: - -- Create Cloud provider credentials -- Define Resource classes -- Create a target Kubernetes cluster (using dynamic provisioning with the cluster resource class) - -**Note**: all artifacts created by the administrator are stored/hosted in the `crossplane-system` namespace, which has -a restricted access, i.e. `Application Owner(s)` do not have access to them. - -For the next steps, make sure your `kubectl` context points to the `Crossplane` cluster - -- Export Project ID - - **NOTE** you can skip this step if you generated GCP Service Account using `gcloud` - ```bash - export DEMO_PROJECT_ID=[your-demo-project-id] - ``` - -- Patch and Apply `provider.yaml`: - ```bash - sed "s/BASE64ENCODED_CREDS/`cat key.json|base64 | tr -d '\n'`/g;s/DEMO_PROJECT_ID/$DEMO_PROJECT_ID/g" cluster/examples/workloads/wordpress-gcp/provider.yaml | kubectl create -f - - ``` - - - Verify that GCP Provider is in READY state - ```bash - kubectl -n crossplane-system get providers.gcp.crossplane.io -o custom-columns=NAME:.metadata.name,STATUS:.status.Conditions[0].Type,PROJECT-ID:.spec.projectID - ``` - Your output should look similar to: - ```bash - NAME STATUS PROJECT-ID - gcp-provider Ready [your-project-id] - ``` - - - Verify that Resource Classes have been created - ```bash - kubectl -n crossplane-system get resourceclass -o custom-columns=NAME:metadata.name,PROVISIONER:.provisioner,PROVIDER:.providerRef.name,RECLAIM-POLICY:.reclaimPolicy - ``` - Your output should be: - ```bash - NAME PROVISIONER PROVIDER RECLAIM-POLICY - standard-cluster gkecluster.compute.gcp.crossplane.io/v1alpha1 gcp-provider Delete - standard-mysql cloudsqlinstance.database.gcp.crossplane.io/v1alpha1 gcp-provider Delete - ``` -- Create a target Kubernetes cluster where `Application Owner(s)` will deploy their `WorkLoad(s)` - - As administrator, you will create a Kubernetes cluster leveraging existing Kubernetes cluster `ResourceClass` and - `Crossplane` Kubernetes cluster dynamic provisioning. - ```bash - kubectl apply -f cluster/examples/workloads/wordpress-gcp/kubernetes.yaml - ``` - - - Verify that Kubernetes Cluster resource was created - ```bash - kubectl -n crossplane-system get kubernetescluster -o custom-columns=NAME:.metadata.name,CLUSTERCLASS:.spec.classReference.name,CLUSTERREF:.spec.resourceName.name - ``` - - Your output should look similar to: - ```bash - NAME CLUSTERCLASS CLUSTERREF - demo-gke-cluster standard-cluster gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99 - ``` - - - Verify that Target GKE cluster was successfully created - ```bash - kubectl -n crossplane-system get gkecluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.zone,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy - ``` - - Your output should look similar to: - ```bash - NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY - gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99 RUNNING gke-6742fe8d-f5b3-11e8-9cec-9cb6d08bde99 146.148.93.40 us-central1-a standard-cluster Delete - ``` - -To recap, as administrator user, you have: -- Defined a `Provider` with Google Service Account credentials -- Defined `ResourceClasses` for `KubernetesCluster` and `CloudSQLInstance` -- Provisioned (dynamically) a GKE Cluster using the `ResourceClass` - -### As Application Owner -you will perform following tasks - -- Define Workload in terms of Resources and Payload (Deployment/Service) which will be deployed onto a Target Kubernetes Cluster -- Define dependency resource requirements, in this case `MySQL` database - -#### MySQL -First, let's take a look at the dependency resource -```yaml -## WordPress MySQL Database Instance -apiVersion: storage.crossplane.io/v1alpha1 -kind: MySQLInstance -metadata: - name: demo - namespace: default -spec: - classReference: - name: standard-mysql - namespace: crossplane-system - engineVersion: "5.7" -``` - -This will request to create a `MySQLInstance` version 5.7, which will be fulfilled by the `standard-mysql` ResourceClass. - -Note, the Application Owner is not aware of any further specifics when it comes down to `MySQLInstance` beyond the engine version. - -#### Workload -```yaml -## WordPress Workload -apiVersion: compute.crossplane.io/v1alpha1 -kind: Workload -metadata: - name: demo - namespace: default -spec: - resources: - - name: demo - secretName: demo - targetCluster: - name: demo-gke-cluster - namespace: crossplane-system - targetDeployment: - apiVersion: extensions/v1beta1 - kind: Deployment - metadata: - name: wordpress - labels: - app: wordpress - spec: - selector: - app: wordpress - strategy: - type: Recreate - template: - metadata: - labels: - app: wordpress - spec: - containers: - - name: wordpress - image: wordpress:4.6.1-apache - env: - - name: WORDPRESS_DB_HOST - valueFrom: - secretKeyRef: - name: demo - key: endpoint - - name: WORDPRESS_DB_USER - valueFrom: - secretKeyRef: - name: demo - key: username - - name: WORDPRESS_DB_PASSWORD - valueFrom: - secretKeyRef: - name: demo - key: password - ports: - - containerPort: 80 - name: wordpress - targetNamespace: demo - targetService: - apiVersion: v1 - kind: Service - metadata: - name: wordpress - spec: - ports: - - port: 80 - selector: - app: wordpress - type: LoadBalancer -``` - -The `Workload` definition spawns multiple constructs and kubernetes object. -- Resources: list of the resources required by the payload application. -- TargetCluster: the cluster where the payload application and all its requirements should be deployed. -- TargetNamespace: the namespace on the target cluster -- Workload Payload: - - TargetDeployment - - TargetService - -- Deploy workload - ```bash - kubectl apply -f cluster/examples/workloads/wordpress-gcp/workload.yaml - ``` -- Wait for `MySQLInstance` to be in `Bound` State - - You can check the status via: - ```bash - kubectl get mysqlinstance -o custom-columns=NAME:.metadata.name,VERSION:.spec.engineVersion,STATE:.status.bindingPhase,CLASS:.spec.classReference.name - ``` - Your output should look like: - ```bash - NAME VERSION STATE CLASS - demo 5.7 Bound standard-mysql - ``` - - **Note**: to check on the concrete resource type status as `Administrator` you can run: - ```bash - kubectl -n crossplane-system get cloudsqlinstance -o custom-columns=NAME:.metadata.name,STATUS:.status.state,CLASS:.spec.classRef.name,VERSION:.spec.databaseVersion - ``` - Your output should be similar to: - ```bash - NAME STATUS CLASS VERSION - mysql-2fea0d8e-f5bb-11e8-9cec-9cb6d08bde99 RUNNABLE standard-mysql MYSQL_5_7 - ``` - -- Wait for `Workload` External IP Address - ```bash - kubectl get workload -o custom-columns=NAME:.metadata.name,CLUSTER:.spec.targetCluster.name,NAMESPACE:.spec.targetNamespace,DEPLOYMENT:.spec.targetDeployment.metadata.name,SERVICE-EXTERNAL-IP:.status.service.loadBalancer.ingress[0].ip - ``` - **Note** the `Workload` is defined in Application Owner's (`default`) namespace - - Your output should look similar to: - ```bash - NAME CLUSTER NAMESPACE DEPLOYMENT SERVICE-EXTERNAL-IP - demo demo-gke-cluster demo wordpress 35.193.100.113 - ``` - -- Verify that `WordPress` service is accessible via `SERVICE-EXTERNAL-IP` by: - - Navigate in your browser to `SERVICE-EXTERNAL-IP` - -## Clean Up - -- Remove `Workload` -```bash -kubectl delete -f cluster/examples/workloads/wordpress-gcp/workload.yaml -``` - -- Remove `KubernetesCluster` -```bash -kubectl delete -f cluster/examples/workloads/wordpress-gcp/kubernetes.yaml -``` - -- Remove GCP Provider and ResourceClasses -```bash -kubectl delete -f cluster/examples/workloads/wordpress-gcp/provider.yaml -``` - -- Delete Google Project -```bash -# list all your projects -gcloud projects list - -# delete demo project -gcloud projects delete [demo-project-id -```