docs snapshot for crossplane version `master`

This commit is contained in:
Crossplane 2019-09-18 16:04:35 +00:00
parent 253a8b386c
commit c6571d5b24
5 changed files with 310 additions and 193 deletions

View File

@ -156,10 +156,10 @@ Use [stack-gcp][stack-gcp], [stack-aws][stack-aws], and [stack-azure][stack-azur
[services-user-guide]: services-guide.md [services-user-guide]: services-guide.md
[stack-user-guide]: stacks-guide.md [stack-user-guide]: stacks-guide.md
[stack-developer-guide]: developer-guide.md [stack-developer-guide]: developer-guide.md
[stack-manager]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#terminology [stacks-manager]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#terminology
[crossplane-cli]: https://github.com/crossplaneio/crossplane-cli [crossplane-cli]: https://github.com/crossplaneio/crossplane-cli
[crossplane-cli-usage]: https://github.com/crossplaneio/crossplane-cli#usage [crossplane-cli-usage]: https://github.com/crossplaneio/crossplane-cli#usage
[stack-sercurity-design]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-stacks-security-isolation.md [stack-security-design]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-stacks-security-isolation.md
[stack-wordpress-registry]: https://hub.docker.com/r/crossplane/sample-stack-wordpress [stack-wordpress-registry]: https://hub.docker.com/r/crossplane/sample-stack-wordpress
[stack-wordpress]: https://github.com/crossplaneio/sample-stack-wordpress [stack-wordpress]: https://github.com/crossplaneio/sample-stack-wordpress

View File

@ -1,54 +1,56 @@
--- ---
title: "AWS Stack Setup" title: "Stacks Guide: AWS Setup"
toc: true toc: true
weight: 530 weight: 530
indent: true indent: true
--- ---
# Crossplane Stacks Guide: AWS Setup # Stacks Guide: AWS Setup
## Table of Contents ## Table of Contents
1. [Crossplane Stacks Guide: AWS Setup](#crossplane-stacks-guide-aws-setup)
1. [Table of Contents](#table-of-contents)
1. [Introduction](#introduction) 1. [Introduction](#introduction)
1. [Before you begin](#before-you-begin) 1. [Install the AWS stack](#install-the-aws-stack)
1. [Install AWS stack](#install-aws-stack)
1. [Configure the AWS account](#configure-the-aws-account) 1. [Configure the AWS account](#configure-the-aws-account)
1. [Configure Crossplane Provider for 1. [Configure Crossplane Provider for
AWS](#configure-crossplane-provider-for-aws) AWS](#configure-crossplane-provider-for-aws)
1. [Set Up Network Configuration](#set-up-network-configuration) 1. [Set Up Network Configuration](#set-up-network-configuration)
1. [Configure Provider Resources](#configure-provider-resources) 1. [Configure Provider Resources](#configure-provider-resources)
1. [Recap](#recap) 1. [Recap](#recap)
1. [Next Steps](#next-steps)
## Introduction ## Introduction
In this guide we are focusing on WordPress stack, and will show how it could be In this guide, we will set up an AWS provider in Crossplane so that we
deployed using AWS resources. WordPress stack uses a generic Kubernetes cluster can install and use the [WordPress sample
and a MySQL database as its resource, which are not tied to a specific provider stack][sample-wordpress-stack], which depends on MySQL and Kubernetes!
(also known as **resource claims**). Instead, these resource claims could be
configured to use a be satisfied by a specific cloud provider.
We will walk you through installing the AWS stack, configuring an aws account, Before we begin, you will need:
and setting up cloud-specific resources in order to create and configure a
network configuration in which these cloud resources can communicate with each
other. Once the network configuration is done, we will specify a resource class
for each resource claim type. Then we will install WordPress stack, which will
create related external resources for each claim in AWS.
## Before you begin * Everything from the [Crossplane Stacks Guide][stacks-guide] before the
cloud provider setup
- A `kubectl` pointing to a Crossplane control cluster
- The [Crossplane CLI][crossplane-cli] installed
* An account on [AWS][aws]
* The [aws cli][installed]
Before continuing in this guide, make sure that all the following are true: At the end, we will have:
- Crossplane is installed * A Crossplane control cluster configured to use AWS
- [crossplane-cli] is installed * The boilerplate of an AWS-based project spun up
- `kubectl` is configured to target the Crossplane cluster * Support in the control cluster for managing MySQL and Kubernetes
- An aws account is available cluster dependencies
* A slightly better understanding of:
- The way cloud providers are configured in Crossplane
- The way dependencies for cloud-portable workloads are configured in
Crossplane
## Install AWS stack ## Install the AWS stack
Once Crossplane is installed, it can be extended to support AWS by installing After Crossplane has been installed, it can be extended with more
AWS **stack**. functionality by installing a [Crossplane Stack][stack-docs]! Let's
install the [stack for Amazon Web Services][stack-aws] (AWS) to add
support for that cloud provider.
The namespace where we install the stack, is also the one that our managed AWS The namespace where we install the stack, is also the one that our managed AWS
resources will reside. Let's call this namespace `infra-aws`, and go ahead and resources will reside. Let's call this namespace `infra-aws`, and go ahead and
@ -61,38 +63,37 @@ INFRA_NAMESPACE=infra-aws
kubectl create namespace ${INFRA_NAMESPACE} kubectl create namespace ${INFRA_NAMESPACE}
``` ```
The output will look like the following: Now we can install the AWS stack using Crossplane CLI. Since this is an
infrastructure stack, we need to specify that it's cluster-scoped by
```bash passing the `--cluster` flag.
namespace/infra-aws created
```
Now we can create the AWS stack by using Crossplane CLI. Since this is an
infrastructure stack, we need to specify that it's cluster-scoped via
`--cluster` flag.
```bash ```bash
kubectl crossplane stack generate-install --cluster 'crossplane/stack-aws:master' stack-aws | kubectl apply --namespace ${INFRA_NAMESPACE} -f - kubectl crossplane stack generate-install --cluster 'crossplane/stack-aws:master' stack-aws | kubectl apply --namespace ${INFRA_NAMESPACE} -f -
``` ```
The next steps assume that you installed the AWS stack into the `infra-aws` The rest of the steps assume that you installed the AWS stack into the
namespace. `infra-aws` namespace.
## Configure the AWS account ## Configure the AWS account
An [aws user] with `Administrative` privileges is needed to enable Crossplane to An [aws user][] with `Administrative` privileges is needed to enable Crossplane to
create the required resources. Once the user is provisioned, an [Access Key] create the required resources. Once the user is provisioned, an [Access Key][]
needs to be created to enable the user to have API access. Next, using these set needs to be created so the user can have API access.
of access key credentials, one needs to have [`aws` command line tool]
[installed] and [configured]. Then, the credentials and configuration will
reside in `~/.aws/credentials` and `~/.aws/config` respectively, which will be
consumed in the next step.
When configuring aws CLI, it is recommended that the user credentials are Using the set of access key credentials for the user with the right
configured under a specific [aws named profile] other than `default`. In this access, we will to have [`aws` command line tool][] [installed][], and
guide we are assuming that the credentials are configured under then we will need to [configure it][aws-cli-configure].
`crossplane-user` profile, but you can use other profiles as well. Let's store
the profile name in `aws_profile` variable to use later: When the aws cli is configured, the credentials and configuration will
be in `~/.aws/credentials` and `~/.aws/config` respectively. These will
be consumed in the next step.
When configuring the aws cli, it is recommended that the user credentials are
configured under a specific [aws named profile][], and not under
`default`. In this guide, we assume that the credentials are configured
under the `crossplane-user` profile, but you can use a different profile
name if you want. Let's store the profile name in a variable so we can
use it in later steps:
```bash ```bash
aws_profile=crossplane-user aws_profile=crossplane-user
@ -100,10 +101,11 @@ aws_profile=crossplane-user
## Configure Crossplane Provider for AWS ## Configure Crossplane Provider for AWS
Crossplane uses the aws user credentials that was configured in the previous Crossplane uses the aws user credentials that were configured in the previous
step, to create resources in AWS. These credentials will be stored as a step to create resources in AWS. These credentials will be stored as a
[secret], and is managed them by an [`aws provider`] instance. In addition to [secret][] in Kubernetes, and will be used by an [aws
the credentials, the AWS region is also read from the configuration to target a provider][aws-provider-docs] instance. The AWS region is also pulled
from the cli configuration, so that the aws provider can target a
specific region. specific region.
To store the credentials as a secret, run: To store the credentials as a secret, run:
@ -117,7 +119,7 @@ AWS_REGION=$(awk '/["$aws_profile"]/ {getline; print $3}' ${HOME}/.aws/config)
``` ```
At this point, the region and the encoded credentials are stored in respective At this point, the region and the encoded credentials are stored in respective
variables. Next, we'll need to create an instance of [`aws provider`]: variables. Next, we'll need to create an instance of [`aws provider`][]:
```bash ```bash
cat > provider.yaml <<EOF cat > provider.yaml <<EOF
@ -158,25 +160,25 @@ provider.aws.crossplane.io/aws-provider created
When configured in AWS, WordPress resources map to an EKS cluster and an RDS When configured in AWS, WordPress resources map to an EKS cluster and an RDS
database. In order to make the RDS instance accessible from the EKS cluster, database. In order to make the RDS instance accessible from the EKS cluster,
they both need to live within the same VPC. However VPC is not the only AWS they both need to live within the same VPC. However, a VPC is not the only AWS
resource that needs to be created to enable inter-resource connectivity. In resource that needs to be created to enable inter-resource connectivity. In
general, a **Network Configuration**, which is built of a set of VPCs, Subnets, general, a **Network Configuration**, which consists of a set of VPCs, Subnets,
Security Groups, Route Tables, IAM Roles and other resources, is required for Security Groups, Route Tables, IAM Roles and other resources, is required for
this purpose. For more information, see [AWS resource connectivity] design this purpose. For more information, see [AWS resource connectivity][] design
document. document.
In this section we will build a simple network configuration, by creating AWS In this section, we will build a simple network configuration, by creating AWS
resources that are managed by Crossplane. There are a couple of challenges when resources that are managed by Crossplane. There are a couple of challenges when
creating these resources: creating these resources:
- Some of these resources depend on other ones. For instance, a Subnet is - Some of these resources depend on other ones. For instance, a Subnet
dependent on a VPC, so creating a Subnet needs to be done after creating the depends on a VPC, so creating a Subnet needs to be done after creating
VPC. the VPC.
To solve this issue, we will need to create the resoruces in order, so the To solve this issue, we will need to create the resources in order, so
depependent resources are provisioned after creating their dependencies. Since resources are provisioned after their dependencies exist. Since
provisioning a resource might take some time, we need to make sure the provisioning a resource might take some time, we need to make sure the
resource is ready, before moving forward to the next step. Let's create the resource is ready before moving forward to the next step. Let's create the
following function for this purpose: following function for this purpose:
```bash ```bash
@ -192,23 +194,22 @@ creating these resources:
- Some of these resources have identifying attributes that are - Some of these resources have identifying attributes that are
non-deterministic. In other words, they become known after the resource is non-deterministic. In other words, they become known after the resource is
provisioined. For instance, a VPC has a ID (VPC_ID) attribute which is provisioined. For instance, a VPC has an ID (VPC_ID) attribute which is
consumed by other resources (like a Subnet), and only becomes known after the consumed by other resources (such as a Subnet), and the ID only
VPC is created. becomes known after the VPC is created.
To tackle this challege, we will need to retrieve the non-deterministic To tackle this challege, we will need to retrieve the non-deterministic
identifiers of the resources after their creation, and inject them to the identifiers of the resources after their creation, and inject them to the
dependent resources that require those attribute. consumer resources that require those attributes.
The rest of this section creates the resources for a configuration described in The rest of this section creates the resources for a configuration described in
[the EKS user [the EKS user guide][eks-user-guide].
guide](https://docs.aws.amazon.com/eks/latest/userguide/create-public-private-vpc.html). For grouping all these resources together, we will use a `CONFIG_NAME` variable,
For grouping all these resources together we will use a `CONFIG_NAME` variable, which will be prepended to the names of these resources in Crossplane,
which will be prepended to the names of these resources in Crossplane, and their and also their corresponding external resources in AWS. Keep in mind
corresponding external resources in AWS. Keep in mind that if you create that if you create multiple such configurations in the same Crossplane
multiple such configuration in the same Crossplane cluster or the same AWS cluster or the same AWS account, you will need to use different config
account, you will need to use different config names, otherwise there will be names. Otherwise, there will be naming conflicts.
naming conflicts.
```bash ```bash
# the name of the aws network configuration # the name of the aws network configuration
@ -217,7 +218,7 @@ CONFIG_NAME=aws-network-config
### VPC ### VPC
A [Virtual Private Network] or VPC is a virtual network in AWS. A [Virtual Private Network][] or VPC is a virtual network in AWS.
```bash ```bash
# build vpc yaml # build vpc yaml
@ -249,13 +250,13 @@ vpc.network.aws.crossplane.io/aws-network-config-vpc created
vpc.network.aws.crossplane.io/aws-network-config-vpc condition met vpc.network.aws.crossplane.io/aws-network-config-vpc condition met
``` ```
Once the VPC is created, you can see the full object and its status by running Once the VPC is created, you can see the full object and its status by running:
```bash ```bash
kubectl get -f "vpc.yaml" -o yaml kubectl get -f "vpc.yaml" -o yaml
``` ```
The output will look like: The output will look something like:
```yaml ```yaml
apiVersion: network.aws.crossplane.io/v1alpha2 apiVersion: network.aws.crossplane.io/v1alpha2
@ -296,7 +297,8 @@ status:
vpcState: available vpcState: available
``` ```
Now, we can retrieve the VPCID to use in subsequent resources: Now that we have a VPC, we can retrieve the VPCID to use in subsequent
resources and save it to a variable:
```bash ```bash
VPC_ID=$(kubectl get -f "vpc.yaml" -o jsonpath='{.status.vpcId}') VPC_ID=$(kubectl get -f "vpc.yaml" -o jsonpath='{.status.vpcId}')
@ -304,7 +306,7 @@ VPC_ID=$(kubectl get -f "vpc.yaml" -o jsonpath='{.status.vpcId}')
### Subnets ### Subnets
In this configuration we create three public [Subnet]s. In this configuration we create three public [Subnet][]s.
```bash ```bash
# build subnet yaml # build subnet yaml
@ -369,7 +371,8 @@ subnet.network.aws.crossplane.io/aws-network-config-subnet2 condition met
subnet.network.aws.crossplane.io/aws-network-config-subnet3 condition met subnet.network.aws.crossplane.io/aws-network-config-subnet3 condition met
``` ```
We need to retrieve the SubndtIDs for subsequent resources: We need to retrieve the SubnetIDs for subsequent resources and save them
to variables:
```bash ```bash
SUBNET1_ID=$(kubectl get -f "subnets.yaml" -o=jsonpath='{.items[0].status.subnetId}') SUBNET1_ID=$(kubectl get -f "subnets.yaml" -o=jsonpath='{.items[0].status.subnetId}')
@ -379,8 +382,8 @@ SUBNET3_ID=$(kubectl get -f "subnets.yaml" -o=jsonpath='{.items[2].status.subnet
### Internet Gateway ### Internet Gateway
An [Internet Gateway] enables the resources in the VPC to have access to the An [Internet Gateway][] allows the resources in the VPC to have access to the
Internet. Since the WordPress application will be addressed from the internet, Internet. Since the WordPress application will be accessed from the internet,
this resource is required in the network configuration. this resource is required in the network configuration.
```bash ```bash
@ -411,7 +414,7 @@ internetgateway.network.aws.crossplane.io/aws-network-config-internetgateway cre
internetgateway.network.aws.crossplane.io/aws-network-config-internetgateway condition met internetgateway.network.aws.crossplane.io/aws-network-config-internetgateway condition met
``` ```
To retrieve the internete gateway ID (IG_ID): Retrieve the internet gateway's ID (IG_ID) and save it in a variable:
```bash ```bash
IG_ID=$(kubectl get -f "internetgateway.yaml" -o=jsonpath='{.status.internetGatewayId}') IG_ID=$(kubectl get -f "internetgateway.yaml" -o=jsonpath='{.status.internetGatewayId}')
@ -419,9 +422,9 @@ IG_ID=$(kubectl get -f "internetgateway.yaml" -o=jsonpath='{.status.internetGate
### Route Table ### Route Table
A [Route Table] sets rules to direct traffic in a virtual network. We use a A [Route Table][] specifies rules to direct traffic in a virtual network. We use a
Route Table to redirect internet traffic from all Subnets to the Internet Route Table to redirect internet traffic from all Subnets to the Internet
Gateway instance that we created in previous step. Gateway instance that we created in the previous step.
```bash ```bash
# build route table yaml # build route table yaml
@ -460,8 +463,8 @@ routetable.network.aws.crossplane.io/aws-network-config-routetable condition met
### Cluster Security Group ### Cluster Security Group
A [Security Group] is created to later to be assigned to the EKS cluster. This A [Security Group][] is created so that later we can assign it to the EKS cluster. This
security group enables the cluster to communicate with the worker nodes security group allows the cluster to communicate with the worker nodes.
```bash ```bash
# build the cluster security group yaml # build the cluster security group yaml
@ -493,7 +496,8 @@ securitygroup.network.aws.crossplane.io/aws-network-config-cluster-sg created
securitygroup.network.aws.crossplane.io/aws-network-config-cluster-sg condition met securitygroup.network.aws.crossplane.io/aws-network-config-cluster-sg condition met
``` ```
Retrieve the SecurityGroupID for cluster security group: Retrieve the SecurityGroupID for cluster security group and save it to a
variable:
```bash ```bash
CLUSTER_SECURITY_GROUP_ID=$(kubectl get -f "cluster_sg.yaml" -o=jsonpath='{.status.securityGroupID}') CLUSTER_SECURITY_GROUP_ID=$(kubectl get -f "cluster_sg.yaml" -o=jsonpath='{.status.securityGroupID}')
@ -501,9 +505,9 @@ CLUSTER_SECURITY_GROUP_ID=$(kubectl get -f "cluster_sg.yaml" -o=jsonpath='{.stat
### Database Security Group ### Database Security Group
A [Security Group] is created to later to be assigned to the RDS database A [Security Group][] is created so that later we can assign it to the RDS database
instance. This security group enables the database instance to accept traffic instance. This security group allows the database instance to accept traffic
from the internet in a certain port. from the internet on a certain port.
```bash ```bash
# build the rds security group yaml # build the rds security group yaml
@ -542,7 +546,8 @@ securitygroup.network.aws.crossplane.io/aws-network-config-rds-sg created
securitygroup.network.aws.crossplane.io/aws-network-config-rds-sg condition met securitygroup.network.aws.crossplane.io/aws-network-config-rds-sg condition met
``` ```
Retrieve the SecurityGroupID for rds security group: Retrieve the SecurityGroupID for rds security group and store it in a
variable:
```bash ```bash
RDS_SECURITY_GROUP_ID=$(kubectl get -f "rds_sg.yaml" -o=jsonpath='{.status.securityGroupID}') RDS_SECURITY_GROUP_ID=$(kubectl get -f "rds_sg.yaml" -o=jsonpath='{.status.securityGroupID}')
@ -550,7 +555,7 @@ RDS_SECURITY_GROUP_ID=$(kubectl get -f "rds_sg.yaml" -o=jsonpath='{.status.secur
### Database Subnet Group ### Database Subnet Group
A [Database Subnet Group] creates a group of Subnets which can communicate with A [Database Subnet Group][] creates a group of Subnets which can communicate with
an RDS database instance. an RDS database instance.
```bash ```bash
@ -589,7 +594,7 @@ dbsubnetgroup.storage.aws.crossplane.io/aws-network-config-dbsubnetgroup created
dbsubnetgroup.storage.aws.crossplane.io/aws-network-config-dbsubnetgroup condition met dbsubnetgroup.storage.aws.crossplane.io/aws-network-config-dbsubnetgroup condition met
``` ```
We need to retrieve the SubndtIDs for subsequent resources: We need to retrieve the SubnetIDs so other resources can use them:
```bash ```bash
RDS_SUBNET_GROUP_NAME=$(kubectl get -f "dbsubnetgroup.yaml" -o=jsonpath='{.spec.groupName}') RDS_SUBNET_GROUP_NAME=$(kubectl get -f "dbsubnetgroup.yaml" -o=jsonpath='{.spec.groupName}')
@ -597,9 +602,9 @@ RDS_SUBNET_GROUP_NAME=$(kubectl get -f "dbsubnetgroup.yaml" -o=jsonpath='{.spec.
### Cluster IAM Role ### Cluster IAM Role
An [IAM Role] gives permissions to the principal that assumes that role. We An [IAM Role][] gives permissions to the principal which assumes that role. We
Create a role to be assumed by the cluster, which later is granted the required create a role to be assumed by the cluster, which later is granted the
permissions to talk to required resources in AWS. permissions needed to talk to our resources in AWS.
```bash ```bash
# build vpc yaml # build vpc yaml
@ -643,7 +648,7 @@ iamrole.identity.aws.crossplane.io/aws-network-config-eks-cluster-role created
iamrole.identity.aws.crossplane.io/aws-network-config-eks-cluster-role condition met iamrole.identity.aws.crossplane.io/aws-network-config-eks-cluster-role condition met
``` ```
To retrieve the IAM Role Arn: Retrieve the IAM Role Arn and store it in a variable:
```bash ```bash
EKS_ROLE_ARN=$(kubectl get -f "iamrole.yaml" -o=jsonpath='{.status.arn}') EKS_ROLE_ARN=$(kubectl get -f "iamrole.yaml" -o=jsonpath='{.status.arn}')
@ -651,7 +656,7 @@ EKS_ROLE_ARN=$(kubectl get -f "iamrole.yaml" -o=jsonpath='{.status.arn}')
### Cluster IAM Role Policies ### Cluster IAM Role Policies
An [IAM Role Policy] grants a role a certain permission. We add two policies to An [IAM Role Policy][] grants a role a certain permission. We add two policies to
the Cluster IAM Role that we created above. These policies are needed for the the Cluster IAM Role that we created above. These policies are needed for the
cluster to communicate with other aws resources. cluster to communicate with other aws resources.
@ -704,9 +709,10 @@ iamrolepolicyattachment.identity.aws.crossplane.io/aws-network-config-role-clust
Once we have the network configuration set up, we also need to tell Crossplane Once we have the network configuration set up, we also need to tell Crossplane
how to satisfy WordPress's claims for a database and a Kubernetes cluster, using how to satisfy WordPress's claims for a database and a Kubernetes cluster, using
AWS resources. The following resource classes allow the EKSCluster and AWS resources. [Resource classes][resource-classes-docs] serve as
RDSInstance claims to be satisfied, using the network configuration we created templates for the new claims we make. The following resource classes
in the previous step: allow the claims for the database and Kubernetes cluster to be satisfied
with the network configuration we just set up:
```bash ```bash
# build resource classes yaml, by using the configured network resources # build resource classes yaml, by using the configured network resources
@ -761,11 +767,13 @@ EOF
kubectl apply -f "resource_classes.yaml" kubectl apply -f "resource_classes.yaml"
``` ```
So far we have been creating resources in `INFRA_NAMESPACE`, where all resources So far we have been creating resources in `$INFRA_NAMESPACE`, where a
are to configure AWS stack with the AWS account, create a network configuration, bunch of resources live: the ones to configure the AWS stack with the
and define resources classes that will satisfied the claims. Now, we will create AWS account; to create a network configuration; and to define resources
an app namespace and populate it with resources that are used to let Crossplane classes that will satisfy our claims. Now, we will create an app
know how to satisfy the claims. Let's call this namespace `app-project1-dev` namespace and populate it with resources that are used to let Crossplane
know how to satisfy the claims. Let's call this namespace
`app-project1-dev`.
```bash ```bash
# the namespace that the app resources will be created # the namespace that the app resources will be created
@ -776,8 +784,8 @@ kubectl create namespace ${APP_NAMESPACE}
Now that we have a namespace, we need to tell Crossplane which resource classes Now that we have a namespace, we need to tell Crossplane which resource classes
should be used to satisfy our claims in that namespace. We will create [portable should be used to satisfy our claims in that namespace. We will create [portable
classes][portable-classes-docs] that have have references to the cloud-specific classes][portable-classes-docs] that have references to the
classes that we created earlier. cloud-specific classes that we created earlier.
For example, `MySQLInstanceClass` is a portable class. It may refer to AWS's For example, `MySQLInstanceClass` is a portable class. It may refer to AWS's
`RDSInstanceClass`, which is a non-portable class. `RDSInstanceClass`, which is a non-portable class.
@ -824,12 +832,12 @@ on resource claims][resource-claims-docs].
To recap what we've set up now in our environment: To recap what we've set up now in our environment:
- Our provider account, both on the provider side and on the Crossplane side. * Our provider account, both on the provider side and on the Crossplane side.
- A Network Configuration for all instances to share. * A Network Configuration for all instances to share.
- An EKSClusterClass and an RDSInstanceClass with the right configuration to use * An EKSClusterClass and an RDSInstanceClass with the right configuration to use
the mentioned networking setup. the mentioned networking setup.
- A namespace for our app resources to reside with default MySQLInstanceClass * A namespace for our app resources, with a default MySQLInstanceClass and
and KubernetesClusterClass that refer to our EKSClusterClass and a default KubernetesClusterClass that refer to our EKSClusterClass and
RDSInstanceClass. RDSInstanceClass.
## Next Steps ## Next Steps
@ -838,17 +846,32 @@ Next we'll set up a Crossplane App Stack and use it! Head [back over to the
Stacks Guide document][stacks-guide-continue] so we can pick up where we left Stacks Guide document][stacks-guide-continue] so we can pick up where we left
off. off.
<!-- Links -->
[stacks-guide]: stacks-guide.md
[aws]: https://aws.amazon.com
[stack-aws]: https://github.com/crossplaneio/stack-aws
[sample-wordpress-stack]: https://github.com/crossplaneio/sample-stack-wordpress
[stack-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#crossplane-stacks
[aws user]: https://docs.aws.amazon.com/mediapackage/latest/ug/setting-up-create-iam-user.html [aws user]: https://docs.aws.amazon.com/mediapackage/latest/ug/setting-up-create-iam-user.html
[Access Key]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html [Access Key]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
[`aws provider`]: https://github.com/crossplaneio/stack-aws/blob/master/aws/apis/v1alpha2/types.go#L43 [`aws provider`]: https://github.com/crossplaneio/stack-aws/blob/master/aws/apis/v1alpha2/types.go#L43
[aws-provider-docs]: https://github.com/crossplaneio/stack-aws/blob/master/aws/apis/v1alpha2/types.go#L43
[`aws` command line tool]: https://aws.amazon.com/cli/ [`aws` command line tool]: https://aws.amazon.com/cli/
[AWS SDK for GO]: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html [AWS SDK for GO]: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html
[installed]: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html [installed]: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
[configured]: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html [aws-cli-configure]: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html
[AWS security credentials]: https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html [AWS security credentials]: https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html
[secret]: https://kubernetes.io/docs/concepts/configuration/secret/ [secret]: https://kubernetes.io/docs/concepts/configuration/secret/
[aws named profile]: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html [aws named profile]: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
[crossplane-cli]: https://github.com/crossplaneio/crossplane-cli [crossplane-cli]: https://github.com/crossplaneio/crossplane-cli
[Virtual Private Network]: https://aws.amazon.com/vpc/ [Virtual Private Network]: https://aws.amazon.com/vpc/
[Subnet]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html#vpc-subnet-basics [Subnet]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html#vpc-subnet-basics
[AWS resource connectivity]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-resource-connectivity-mvp.md#amazon-web-services [AWS resource connectivity]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-resource-connectivity-mvp.md#amazon-web-services
@ -858,6 +881,10 @@ off.
[Database Subnet Group]: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html [Database Subnet Group]: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html
[IAM Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html [IAM Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
[IAM Role Policy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html [IAM Role Policy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html
[portable-classes-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-default-resource-class.md [portable-classes-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-default-resource-class.md
[stacks-guide-continue]: stacks-guide.html#install-support-for-our-application-into-crossplane [resource-classes-docs]: concepts.md#resource-claims-and-resource-classes
[stacks-guide-continue]: stacks-guide.md#install-support-for-our-application-into-crossplane
[resource-claims-docs]: concepts.md#resource-claims-and-resource-classes [resource-claims-docs]: concepts.md#resource-claims-and-resource-classes
[eks-user-guide]: https://docs.aws.amazon.com/eks/latest/userguide/create-public-private-vpc.html

View File

@ -1,11 +1,11 @@
--- ---
title: "Azure Stack Setup" title: "Stacks Guide: Azure Setup"
toc: true toc: true
weight: 540 weight: 540
indent: true indent: true
--- ---
# Crossplane Stacks Guide: Azure Setup # Stacks Guide: Azure Setup
## Table of Contents ## Table of Contents
@ -20,9 +20,9 @@ indent: true
## Introduction ## Introduction
In this guide, we will set up an Azure provider in Crossplane so that we can In this guide, we will set up an Azure provider in Crossplane so that we
install and use the WordPress sample stack, which depends on MySQL and can install and use the [WordPress sample
Kubernetes! stack][sample-wordpress-stack], which depends on MySQL and Kubernetes!
Before you begin, you will need: Before you begin, you will need:
@ -31,6 +31,7 @@ Before you begin, you will need:
- A `kubectl` pointing to a Crossplane control cluster - A `kubectl` pointing to a Crossplane control cluster
- The [Crossplane CLI][crossplane-cli] installed - The [Crossplane CLI][crossplane-cli] installed
* An account on [Azure][azure] * An account on [Azure][azure]
* The [jq][jq] tool for interacting with some JSON, or equivalent
At the end, we will have: At the end, we will have:
@ -48,24 +49,27 @@ document][crossplane-concepts] for that.
## Install the Azure Stack ## Install the Azure Stack
After Crossplane has been installed, it can be extended with more functionality After Crossplane has been installed, it can be extended with more
by installing a Crossplane Stack! Let's install the stack for Microsoft Azure to functionality by installing a [Crossplane Stack][stack-docs]! Let's
add support for that cloud provider. We can use the Crossplane CLI for this install the [stack for Microsoft Azure][stack-azure] to add
operation: support for that cloud provider. We can use the [Crossplane
CLI][crossplane-cli] for this operation. Since this is an infrastructure
stack, we need to specify that it's cluster-scoped by passing the
`--cluster` flag.
``` To install to a specific namespace, we can use the `generate-install`
kubectl crossplane stack install 'crossplane/stack-azure:master' stack-azure command and pipe it to `kubectl apply` instead, which gives us more
``` control over how the stack's installation is handled. Everything is
To install to a particular namespace, you can use the `generate-install` command a Kubernetes object!
and pipe it to `kubectl apply` instead, which gives you more control over how
the stack's installation is handled. Everything is Kubernetes object!
Since this is an infrastructure stack, we need to specify that it's
cluster-scoped via `--cluster` flag.
``` ```
kubectl crossplane stack generate-install --cluster 'crossplane/stack-azure:master' stack-azure | kubectl apply --namespace crossplane-system -f - kubectl crossplane stack generate-install --cluster 'crossplane/stack-azure:master' stack-azure | kubectl apply --namespace crossplane-system -f -
``` ```
If we wanted to use whatever the current namespace is, we could have
used `kubectl crossplane stack install` instead of using
`generate-install`.
We have installed the Azure stack into the `crossplane-system` namespace, but we We have installed the Azure stack into the `crossplane-system` namespace, but we
want to group our Azure-specific resources in their own environment namespaces. want to group our Azure-specific resources in their own environment namespaces.
For the purpose of this guide, we will create all Azure-specific resources in For the purpose of this guide, we will create all Azure-specific resources in
@ -89,8 +93,8 @@ We will make use of the following services on Azure:
* Subnetwork * Subnetwork
* Virtual Network Rule * Virtual Network Rule
In order to utilize each of these services, you will need to follow the Adding In order to utilize each of these services, you will need to follow the [Adding
Microsoft Azure to Crossplane [guide][provider-azure-guide] to obtain Microsoft Azure to Crossplane guide][provider-azure-guide] to obtain
appropriate credentials in a JSON file referred to as appropriate credentials in a JSON file referred to as
`crossplane-azure-provider-key.json`. `crossplane-azure-provider-key.json`.
@ -144,7 +148,8 @@ other Crossplane resources.
We also will need to use our Azure subscription id to provision some of the We also will need to use our Azure subscription id to provision some of the
resources we will need. You can set an environment variable so that you will resources we will need. You can set an environment variable so that you will
have access when creating resources that require it: have access when creating resources that require it. If you have a JSON
tool like [jq][jq], you can use:
```bash ```bash
export SUBSCRIPTION_ID=$(cat crossplane-azure-provider-key.json | jq -j '.subscriptionId') export SUBSCRIPTION_ID=$(cat crossplane-azure-provider-key.json | jq -j '.subscriptionId')
@ -152,11 +157,12 @@ export SUBSCRIPTION_ID=$(cat crossplane-azure-provider-key.json | jq -j '.subscr
## Set Up Network Resources ## Set Up Network Resources
Wordpress needs a SQL database and a Kubernetes cluster. But *those* two Wordpress needs a SQL database and a Kubernetes cluster. But **those** two
resources need a private network to communicate securely. They must also be resources need a private network to communicate securely. They must also be
deployed into a Resource Group, a service that Azure uses to logically group deployed into a [Resource Group][azure-resource-group-docs], a service
resources together. So, we need to set up these resources before we get to the that Azure uses to logically group resources together. So, we need to
database and Kubernetes creation steps. Here's an example network setup: set up these resources before we get to the database and Kubernetes
creation steps. Here's an example network setup:
``` ```
cat > network.yaml <<EOF cat > network.yaml <<EOF
@ -220,8 +226,8 @@ kubectl apply -f network.yaml
For more details about networking and what happens when you run this command, For more details about networking and what happens when you run this command,
see [this document with more details][crossplane-azure-networking-docs]. see [this document with more details][crossplane-azure-networking-docs].
It should not take too long for these resources to provision. You can monitor It should not take too long for these resources to provision. You can
their status with the following command: check their statuses with the following command:
``` ```
kubectl describe -f network.yaml kubectl describe -f network.yaml
@ -289,21 +295,22 @@ EOF
kubectl apply -f environment.yaml kubectl apply -f environment.yaml
``` ```
The steps that we have taken so far have been related to things that can be The steps that we have taken so far have been related to things that can
shared by all resources in all namespaces of that Crossplane cluster. Now, we be shared by all resources in all namespaces of the Crossplane control
will keep going with an app namespace which we will populate with resources that cluster. Now, we will use a namespace specific to our application, and
will help Crossplane know with what configuration it should satisfy the claims. we'll populate it with resources that will help Crossplane know what
You can use any namespace for your app's resources but for this tutorial we'll configuration to use to satisfy our application's resource claims.
use the `app-project1-dev` namespace we created. You can use any namespace for your app's resources, but for this
tutorial we'll use the `app-project1-dev` namespace we created.
Now we need to tell Crossplane which resource classes should be used to satisfy Now we need to tell Crossplane which resource classes should be used to satisfy
our claims in that app namespace. We will create portable classes that have have our claims in that app namespace. We will create portable classes that have have
reference to non-portable ones that we created earlier. In our claims, we can reference to non-portable ones that we created earlier. In our claims, we can
refer to those portable classes directly or label one as the default portable refer to those portable classes directly, or label one as the default portable
class to be used in claims that do not have class reference. class to be used in claims that do not have class reference.
For example, MySQLInstanceClass is a portable class that can refer to Azure's For example, `MySQLInstanceClass` is a portable class that can refer to Azure's
SQLServerClass, which is a cloud-specific class. `SQLServerClass`, which is a cloud-specific class.
``` ```
cat > namespace.yaml <<EOF cat > namespace.yaml <<EOF
@ -381,8 +388,9 @@ while kubectl -n azure-infra-dev get mysqlservers -o yaml | grep -q 'items: \[\
echo -n "." >&2 echo -n "." >&2
sleep 5 sleep 5
done done
echo "done" >&2
export MYSQL_NAME=$(kubectl -n azure-infra-dev get mysqlservers -o json | jq -j '.items[0].metadata.name') export MYSQL_NAME=$(kubectl -n azure-infra-dev get mysqlservers -o=jsonpath='{.items[0].metadata.name}')
sed "s/MYSQL_NAME/$MYSQL_NAME/g" vnet-rule.yaml | kubectl apply -f - sed "s/MYSQL_NAME/$MYSQL_NAME/g" vnet-rule.yaml | kubectl apply -f -
@ -391,6 +399,9 @@ EOF
chmod +x vnetwatch.sh && ./vnetwatch.sh chmod +x vnetwatch.sh && ./vnetwatch.sh
``` ```
The script should be left running in the background while we go through
the rest of the guide and install the Wordpress stack.
## Recap ## Recap
To recap what we've set up now in our environment: To recap what we've set up now in our environment:
@ -415,15 +426,22 @@ Stacks Guide document][stacks-guide-continue] so we can pick up where we left
off. off.
<!-- Links --> <!-- Links -->
[crossplane-cli]: https://github.com/crossplaneio/crossplane-cli [sample-wordpress-stack]: https://github.com/crossplaneio/sample-stack-wordpress
[crossplane-azure-networking-docs]: TODO
[stacks-guide]: stacks-guide.html [crossplane-cli]: https://github.com/crossplaneio/crossplane-cli/tree/release-0.1
[crossplane-azure-networking-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-resource-connectivity-mvp.md#microsoft-azure
[stacks-guide]: stacks-guide.md
[provider-azure-guide]: cloud-providers/azure/azure-provider.md [provider-azure-guide]: cloud-providers/azure/azure-provider.md
[crossplane-concepts]: TODO [stack-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#crossplane-stacks
[portable-claims]: TODO [stack-azure]: https://github.com/crossplaneio/stack-azure
[crossplane-concepts]: concepts.md
[portable-classes-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-default-resource-class.md
[azure]: https://azure.microsoft.com [azure]: https://azure.microsoft.com
[azure-vnet-rule]: https://docs.microsoft.com/en-us/azure/mysql/concepts-data-access-and-security-vnet [azure-vnet-rule]: https://docs.microsoft.com/en-us/azure/mysql/concepts-data-access-and-security-vnet
[azure-resource-group-docs]: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview
[stacks-guide-continue]: stacks-guide.html#install-support-for-our-application-into-crossplane [stacks-guide-continue]: stacks-guide.md#install-support-for-our-application-into-crossplane
[jq]: https://stedolan.github.io/jq/

View File

@ -1,11 +1,11 @@
--- ---
title: "GCP Stack Setup" title: "Stacks Guide: GCP Setup"
toc: true toc: true
weight: 520 weight: 520
indent: true indent: true
--- ---
# Crossplane Stacks Guide: GCP Setup # Stacks Guide: GCP Setup
## Table of Contents ## Table of Contents
@ -56,7 +56,6 @@ CLI][crossplane-cli] for this operation. Since this is an infrastructure
stack, we need to specify that it's cluster-scoped by passing the stack, we need to specify that it's cluster-scoped by passing the
`--cluster` flag. `--cluster` flag.
To install to a specific namespace, we can use the `generate-install` To install to a specific namespace, we can use the `generate-install`
command and pipe it to `kubectl apply` instead, which gives us more command and pipe it to `kubectl apply` instead, which gives us more
control over how the stack's installation is handled. Everything is control over how the stack's installation is handled. Everything is
@ -83,6 +82,22 @@ resource claims][resource-claims-docs].
For convenience, the next steps assume that you installed GCP stack into For convenience, the next steps assume that you installed GCP stack into
the `gcp` namespace. the `gcp` namespace.
### Validate the installation
To check to see whether our stack installed correctly, we can look at
the status of our stack:
```
kubectl -n gcp get stack
```
It should look something like this:
```
NAME READY VERSION AGE
stack-gcp True 0.0.1 5m19s
```
## Configure GCP Account ## Configure GCP Account
We will make use of the following services on GCP: We will make use of the following services on GCP:
@ -111,14 +126,15 @@ assigned][gcp-assign-roles]:
* Kubernetes Engine Admin * Kubernetes Engine Admin
* Service Account User * Service Account User
You need to get JSON file of the service account youll use. In the next ### Set up cloud provider credentials
sections, this file will be referred to as
`crossplane-gcp-provider-key.json`
You can create the JSON file by using the [gcloud This guide assumes that you have created a JSON file which contains the
command][gcp-create-keys] and specifying a file name of credentials for the cloud provider. In later sections, this file will be
`crossplane-gcp-provider-key.json`. If you use Crossplane's [GCP referred to as `crossplane-gcp-provider-key.json`. There are quite a few
credentials script][gcp-credentials], this is taken care of for you. steps involved, so the steps are in [a different document which you
should take a look at][cloud-provider-setup-gcp] before moving to the
next section. Or, there is also [a script in the Crossplane
repo][gcp-credentials] which helps with creating the file.
## Configure Crossplane GCP Provider ## Configure Crossplane GCP Provider
@ -177,6 +193,21 @@ The name of the `Provider` resource in the file above is `gcp-provider`;
we'll use the name `gcp-provider` to refer to this provider when we we'll use the name `gcp-provider` to refer to this provider when we
configure and set up other Crossplane resources. configure and set up other Crossplane resources.
### Validate
To check on our newly created provider, we can run:
```
kubectl -n gcp get provider.gcp.crossplane.io
```
The output should look something like:
```
NAME PROJECT-ID AGE
gcp-provider crossplane-playground 37s
```
## Set Up Network Resources ## Set Up Network Resources
Wordpress needs a SQL database and a Kubernetes cluster. But **those** Wordpress needs a SQL database and a Kubernetes cluster. But **those**
@ -278,6 +309,17 @@ assumes the GCP stack is installed in `gcp` namespace:
kubectl -n gcp get connection.servicenetworking.gcp.crossplane.io/example-connection -o custom-columns='NAME:.metadata.name,FIRST_CONDITION:.status.conditions[0].status,SECOND_CONDITION:.status.conditions[1].status' kubectl -n gcp get connection.servicenetworking.gcp.crossplane.io/example-connection -o custom-columns='NAME:.metadata.name,FIRST_CONDITION:.status.conditions[0].status,SECOND_CONDITION:.status.conditions[1].status'
``` ```
The output should look something like:
```
NAME FIRST_CONDITION SECOND_CONDITION
example-connection True True
```
The conditions we're checking for are `Ready` and `Synced`. The reason
we are using `FIRST_CONDITION` and `SECOND_CONDITION` is because we
don't know what order they'll be in when we run the command.
## Configure Provider Resources ## Configure Provider Resources
Once we have the network set up, we also need to tell Crossplane how to Once we have the network set up, we also need to tell Crossplane how to
@ -331,9 +373,13 @@ EOF
kubectl apply -f environment.yaml kubectl apply -f environment.yaml
``` ```
The example YAML also exists in [the Crossplane The example YAML also exists in [the Crossplane
repository][crossplane-sample-gcp-environment]. repository][crossplane-sample-gcp-environment].
We don't need to validate that these are ready, because they don't
require any reconciliation.
The steps that we have taken so far have been related to things that can The steps that we have taken so far have been related to things that can
be shared by all resources in all namespaces of the Crossplane control be shared by all resources in all namespaces of the Crossplane control
cluster. Now, we will use a namespace specific to our application, and cluster. Now, we will use a namespace specific to our application, and
@ -397,6 +443,9 @@ kubectl apply -f namespace.yaml
The example YAML also exists in [the Crossplane The example YAML also exists in [the Crossplane
repository][crossplane-sample-gcp-namespace]. repository][crossplane-sample-gcp-namespace].
We don't need to validate that these are ready, because they don't need
to reconcile for them to be ready.
## Recap ## Recap
To recap what we've set up now in our environment: To recap what we've set up now in our environment:
@ -421,7 +470,7 @@ the Stacks Guide document][stacks-guide-continue] so we can pick up
where we left off. where we left off.
<!-- Links --> <!-- Links -->
[crossplane-cli]: https://github.com/crossplaneio/crossplane-cli [crossplane-cli]: https://github.com/crossplaneio/crossplane-cli/tree/release-0.1
[crossplane-gcp-networking-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-resource-connectivity-mvp.md#google-cloud-platform [crossplane-gcp-networking-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-resource-connectivity-mvp.md#google-cloud-platform
[stacks-guide]: stacks-guide.md [stacks-guide]: stacks-guide.md
@ -448,3 +497,5 @@ where we left off.
[crossplane-sample-gcp-network]: https://github.com/crossplaneio/crossplane/blob/master/cluster/examples/workloads/kubernetes/wordpress/gcp/network.yaml [crossplane-sample-gcp-network]: https://github.com/crossplaneio/crossplane/blob/master/cluster/examples/workloads/kubernetes/wordpress/gcp/network.yaml
[crossplane-sample-gcp-environment]: https://github.com/crossplaneio/crossplane/blob/master/cluster/examples/workloads/kubernetes/wordpress/gcp/environment.yaml [crossplane-sample-gcp-environment]: https://github.com/crossplaneio/crossplane/blob/master/cluster/examples/workloads/kubernetes/wordpress/gcp/environment.yaml
[crossplane-sample-gcp-namespace]: https://github.com/crossplaneio/crossplane/blob/master/cluster/examples/workloads/kubernetes/wordpress/gcp/namespace.yaml [crossplane-sample-gcp-namespace]: https://github.com/crossplaneio/crossplane/blob/master/cluster/examples/workloads/kubernetes/wordpress/gcp/namespace.yaml
[cloud-provider-setup-gcp]: cloud-providers/gcp/gcp-provider.md

View File

@ -5,7 +5,7 @@ weight: 510
indent: false indent: false
--- ---
# Crossplane Stacks Guide # Stacks Guide
## Table of Contents ## Table of Contents
@ -43,14 +43,17 @@ Let's go!
## Concepts ## Concepts
There are a bunch of things you might want to know to fully understand what's happening in this document. This guide won't cover them, but there are other ones that do. Here are some links! There are a bunch of things you might want to know to fully understand
what's happening in this document. This guide won't cover them, but
there are other ones that do. Here are some links!
* [Crossplane concepts][crossplane-concepts] * [Crossplane concepts][crossplane-concepts]
* [Kubernetes concepts][kubernetes-concepts] * [Kubernetes concepts][kubernetes-concepts]
## Before you get started ## Before you get started
This guide assumes you are using a *nix-like environment. It also assumes you have a basic working familiarity with the following: This guide assumes you are using a *nix-like environment. It also
assumes you have a basic working familiarity with the following:
* The terminal environment * The terminal environment
* Setting up cloud provider accounts for the cloud provider you want to * Setting up cloud provider accounts for the cloud provider you want to
@ -73,8 +76,7 @@ CLI][crossplane-cli], because it's more convenient. To install it, we
can use the one-line curl bash: can use the one-line curl bash:
``` ```
RELEASE=0.0.1 RELEASE=release-0.1 && curl -sL https://raw.githubusercontent.com/crossplaneio/crossplane-cli/"${RELEASE}"/bootstrap.sh | RELEASE=${RELEASE} bash
curl -sL https://raw.githubusercontent.com/crossplaneio/crossplane-cli/"${RELEASE}"/bootstrap.sh | bash
``` ```
To use the latest release, you can use `master` as the `RELEASE` instead To use the latest release, you can use `master` as the `RELEASE` instead
@ -103,7 +105,7 @@ documentation][crossplane-install-docs].
### Create the application namespace ### Create the application namespace
[Kubernetes namespaces][kubernetes-namespace-docs] are used to isolate [Kubernetes namespaces][kubernetes-namespaces-docs] are used to isolate
resources in the same cluster, and we'll use them in our Crossplane resources in the same cluster, and we'll use them in our Crossplane
control cluster too. Let's create a namespace for our application's control cluster too. Let's create a namespace for our application's
resources. We'll call it `app-project1-dev` for the purposes of this resources. We'll call it `app-project1-dev` for the purposes of this
@ -180,6 +182,19 @@ EOF
kubectl apply --namespace app-project1-dev -f my-wordpress.yaml kubectl apply --namespace app-project1-dev -f my-wordpress.yaml
``` ```
To validate that it has been set up correctly, we can run:
```
kubectl -n app-project1-dev get stack
```
The output should look something like:
```
NAME READY VERSION AGE
sample-stack-wordpress True 0.0.1 48s
```
If the control cluster doesn't recognize the Wordpress instance type, it If the control cluster doesn't recognize the Wordpress instance type, it
could be because the stack is still being installed. Wait a few seconds, could be because the stack is still being installed. Wait a few seconds,
and try creating the Wordpress instance again. and try creating the Wordpress instance again.
@ -203,6 +218,11 @@ kubectl get -n app-project1-dev kubernetesapplication
kubectl get -n app-project1-dev kubernetesapplicationresource kubectl get -n app-project1-dev kubernetesapplicationresource
``` ```
For validation that these resources are spinning up, you can check in
the usual way for your cloud provider, or you can ask for the
statuses of some of the cloud-specific Kubernetes resources provided by
the infrastructure stack that we installed.
For more information about how Crossplane manages databases and For more information about how Crossplane manages databases and
Kubernetes clusters for us, see the more complete documentation about Kubernetes clusters for us, see the more complete documentation about
[claims][claims-docs], [resource classes][resource-classes-docs], and [claims][claims-docs], [resource classes][resource-classes-docs], and
@ -217,7 +237,7 @@ which represents the workload's service. Here's a way to watch for the
ip: ip:
``` ```
kubectl get kubernetesapplicationresource -n app-project1-dev -o custom-columns='NAME:.metadata.name,NAMESPACE:.spec.template.metadata.namespace,KIND:.spec.template.kind,SERVICE-EXTERNAL-IP:.status.remote.loadBalancer.ingress[0].ip' --watch kubectl get --watch kubernetesapplicationresource -n app-project1-dev -o custom-columns='NAME:.metadata.name,NAMESPACE:.spec.template.metadata.namespace,KIND:.spec.template.kind,SERVICE-EXTERNAL-IP:.status.remote.loadBalancer.ingress[0].ip'
``` ```
The ip will show up on the one which has a `Service` kind. The ip will show up on the one which has a `Service` kind.
@ -243,8 +263,7 @@ kubectl delete -n app-project1-dev wordpressinstance my-wordpressinstance
We can also remove the stack, using the Crossplane CLI: We can also remove the stack, using the Crossplane CLI:
``` ```
kubectl crossplane stack uninstall sample-stack-wordpress -n kubectl crossplane stack uninstall sample-stack-wordpress -n app-project1-dev
app-project1-dev
``` ```
Removing the stack removes any Wordpress instances that were created. Removing the stack removes any Wordpress instances that were created.
@ -282,12 +301,13 @@ guide][stack-developer-guide].
## References ## References
* [The Crossplane Concepts guide][crossplane-concepts] * [The Crossplane Concepts guide][crossplane-concepts]
* [Crossplane API Reference][crossplane-api-reference]
* [The Stacks Concepts guide][stack-concepts] * [The Stacks Concepts guide][stack-concepts]
* [Crossplane Install Guide][crossplane-install-docs] * [Crossplane Install Guide][crossplane-install-docs]
* [The Crossplane CLI][crossplane-cli] * [The Crossplane CLI][crossplane-cli]
* [Stacks Quick Start][stack-quick-start] * [Stacks Quick Start][stack-quick-start]
* [Stack Registry][stack-registry]
* [Stacks Developer Guide][stack-developer-guide] * [Stacks Developer Guide][stack-developer-guide]
* [Stack Registry][stack-registry]
* [Provider Stack Developer Guide][provider-stack-developer-guide] * [Provider Stack Developer Guide][provider-stack-developer-guide]
* [AWS documentation][aws-docs] * [AWS documentation][aws-docs]
* [GCP documentation][gcp-docs] * [GCP documentation][gcp-docs]
@ -295,12 +315,13 @@ guide][stack-developer-guide].
* [Kubernetes documentation][kubernetes-docs] * [Kubernetes documentation][kubernetes-docs]
<!-- Named links --> <!-- Named links -->
[crossplane-cli]: https://github.com/crossplaneio/crossplane-cli [crossplane-cli]: https://github.com/crossplaneio/crossplane-cli/tree/release-0.1
[crossplane-cli-docs]: https://github.com/crossplaneio/crossplane-cli/blob/master/README.md [crossplane-cli-docs]: https://github.com/crossplaneio/crossplane-cli/blob/release-0.1/README.md
[crossplane-concepts]: concepts.md [crossplane-concepts]: concepts.md
[crossplane-install-docs]: install-crossplane.md [crossplane-install-docs]: install-crossplane.md
[crossplane-api-reference]: api.md
[kubernetesapplicationresource-docs]: TODO [kubernetesapplicationresource-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-complex-workloads.md
[claims-docs]: concepts.md#resource-claims-and-resource-classes [claims-docs]: concepts.md#resource-claims-and-resource-classes
[resource-classes-docs]: concepts.md#resource-claims-and-resource-classes [resource-classes-docs]: concepts.md#resource-claims-and-resource-classes
[portable-classes-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-default-resource-class.md [portable-classes-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/one-pager-default-resource-class.md
@ -317,15 +338,15 @@ guide][stack-developer-guide].
[gcp-docs]: https://cloud.google.com/docs/ [gcp-docs]: https://cloud.google.com/docs/
[azure-docs]: https://docs.microsoft.com/azure/ [azure-docs]: https://docs.microsoft.com/azure/
[aws-setup]: TODO [aws-setup]: stacks-guide-aws.md
[gcp-setup]: stacks-guide-gcp.md [gcp-setup]: stacks-guide-gcp.md
[azure-setup]: TODO [azure-setup]: stacks-guide-azure.md
[stack-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#crossplane-stacks [stack-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#crossplane-stacks
[stack-quick-start]: https://github.com/crossplaneio/crossplane-cli#quick-start-stacks [stack-quick-start]: https://github.com/crossplaneio/crossplane-cli/tree/release-0.1#quick-start-stacks
[stack-concepts]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#crossplane-stacks [stack-concepts]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#crossplane-stacks
[stack-registry]: https://hub.docker.com/search?q=crossplane&type=image
[stack-manager-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#installation-flow [stack-manager-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#installation-flow
[stack-format-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#stack-package-format [stack-format-docs]: https://github.com/crossplaneio/crossplane/blob/master/design/design-doc-stacks.md#stack-package-format
[stack-registry]: TODO [stack-developer-guide]: developer-guide.md
[stack-developer-guide]: TODO [provider-stack-developer-guide]: developer-guide.md
[provider-stack-developer-guide]: TODO