Skip to content

Commit

Permalink
AWS PCA Issuer (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
anshrma authored Apr 28, 2022
1 parent c671183 commit acd5ffa
Show file tree
Hide file tree
Showing 13 changed files with 734 additions and 2 deletions.
110 changes: 110 additions & 0 deletions docs/add-ons/aws-privateca-issuer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# aws-privateca-issuer

AWS ACM Private CA is a module of the [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/) that can setup and manage private CAs. `cert-manager` is a Kubernetes add-on to automate the management and issuance of TLS certificates from various issuing sources. It will ensure certificates are valid and up to date periodically, and attempt to renew certificates at an appropriate time before expiry. This module `aws-pca-issuer` is a addon for `cert-manager` that issues certificates using AWS ACM PCA.

See the [aws-privateca-issuer documentation](https://cert-manager.github.io/aws-privateca-issuer/).

## Usage

aws_privateca_issuer can be deployed by enabling the add-on via the following.

```hcl
enable_cert_manager = true
enable_aws_privateca_issuer = true
```

Create `AWSPCAClusterIssuer` custom resource definition (CRD). It is a Kubernetes resources that represent certificate authorities (CAs) from AWS ACM and are able to generate signed certificates by honoring certificate signing requests. For more details on external `Issuer` types, please check [aws-privateca-issuer](https://github.com/cert-manager/aws-privateca-issuer)

```hcl
resource "kubernetes_manifest" "cluster-pca-issuer" {
manifest = {
apiVersion = "awspca.cert-manager.io/v1beta1"
kind = "AWSPCAClusterIssuer"
metadata = {
name = "logical.name.of.this.issuer"
}
spec = {
arn = "ARN for AWS PCA"
region: "data.aws_region.current.id OR AWS region of the AWS PCA"
}
}
}
```

Create `Certificate` CRD. Certificates define a desired X.509 certificate which will be renewed and kept up to date. For more details on how to specify and request Certificate resources, please check [Certificate Resources guide](https://cert-manager.io/docs/usage/certificate/).

A Certificate is a namespaced resource that references `AWSPCAClusterIssuer` (created in above step) that determine what will be honoring the certificate request.

```hcl
resource "kubernetes_manifest" "example_pca_certificate" {
manifest = {
apiVersion = "cert-manager.io/v1"
kind = "Certificate"
metadata = {
name = "name of the certificate"
namespace = "default or any namespace"
}
spec = {
commonName = "common name for your certificate"
duration = "duration"
issuerRef = {
group = "awspca.cert-manager.io"
kind = "AWSPCAClusterIssuer"
name: "name of AWSPCAClusterIssuer created above"
}
renewBefore = "360h0m0s"
secretName = "name of the secret where certificate will be mounted"
usages = [
"server auth",
"client auth"
]
privateKey = {
algorithm: "RSA"
size: 2048
}
}
}
}
```

When a Certificate is created, a corresponding CertificateRequest resource is created by `cert-manager` containing the encoded X.509 certificate request, Issuer reference, and other options based upon the specification of the Certificate resource.

This Certificate CRD will tell cert-manager to attempt to use the Issuer (as AWS ACM) to obtain a certificate key pair for the specified domains. If successful, the resulting TLS key and certificate will be stored in a kubernetes secret named , with keys of tls.key, and tls.crt respectively. This secret will live in the same namespace as the Certificate resource.

Now, you may run `kubectl get Certificate` to view the status of Certificate Request from AWS PCA.

```
NAME READY SECRET AGE
example True aws001-preprod-dev-eks-clusterissuer 3h35m
```

If the status is `True`, that means, the `tls.crt`, `tls.key` and `ca.crt` will all be available in [Kubernetes Secret](https://kubernetes.io/docs/concepts/configuration/secret/)

```
aws001-preprod-dev-eks-clusterissuer
Name: aws001-preprod-dev-eks-clusterissuer
Namespace: default
Labels: <none>
Annotations: cert-manager.io/alt-names:
cert-manager.io/certificate-name: example
cert-manager.io/common-name: example.com
cert-manager.io/ip-sans:
cert-manager.io/issuer-group: awspca.cert-manager.io
cert-manager.io/issuer-kind: AWSPCAClusterIssuer
cert-manager.io/issuer-name: aws001-preprod-dev-eks
cert-manager.io/uri-sans:
Type: kubernetes.io/tls
Data
====
ca.crt: 1785 bytes
tls.crt: 1517 bytes
tls.key: 1679 bytes
```
122 changes: 122 additions & 0 deletions examples/tls-with-aws-pca-issuer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# TLS with AWS PCA Issuer
This example deploys the following
- Basic EKS Cluster with VPC
- Creates a new sample VPC, 3 Private Subnets and 3 Public Subnets
- Creates Internet gateway for Public Subnets and NAT Gateway for Private Subnets
- Enables cert-manager module
- Enables aws-privateca-issuer module
- Creates AWS Certificate Manager Private Certificate Authority, enables and activates it
- Creates the CRDs to fetch `tls.crt`, `tls.key` and `ca.crt` , which will be available as Kubernetes Secret. Now you may mount the secret in the application for end to end TLS.

## How to Deploy
### Prerequisites:
Ensure that you have installed the following tools in your Mac or Windows Laptop before start working with this module and run Terraform Plan and Apply
1. [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)
3. [Kubectl](https://Kubernetes.io/docs/tasks/tools/)
4. [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli)

### Deployment Steps
#### Step1: Clone the repo using the command below

```shell script
git clone https://github.com/aws-samples/aws-eks-accelerator-for-terraform.git
```

#### Step2: Run Terraform INIT
Initialize a working directory with configuration files

```shell script
cd examples/tls-with-aws-pca-issuer/
terraform init
```

#### Step3: Run Terraform PLAN
Verify the resources created by this execution

```shell script
export AWS_REGION=<ENTER YOUR REGION> # Select your own region
terraform plan
```

#### Step4: Finally, Terraform APPLY
to create resources

```shell script
terraform apply
```

Enter `yes` to apply

### Configure `kubectl` and test cluster
EKS Cluster details can be extracted from terraform output or from AWS Console to get the name of cluster.
This following command used to update the `kubeconfig` in your local machine where you run kubectl commands to interact with your EKS Cluster.

#### Step5: Run `update-kubeconfig` command

`~/.kube/config` file gets updated with cluster details and certificate from the below command

$ aws eks --region <enter-your-region> update-kubeconfig --name <cluster-name>

#### Step6: List all the worker nodes by running the command below

$ kubectl get nodes

#### Step7: List all the pods running in `aws-privateca-issuer` and `cert-manager` namespace

$ kubectl get pods -n aws-privateca-issuer
$ kubectl get pods -n cert-manager

#### Step8: View the `Certificate` status. It should be in 'Ready' state.

$ kubectl get Certificate

## How to Destroy
The following command destroys the resources created by `terraform apply`

```shell script
cd examples/tls-with-aws-pca-issuer
terraform destroy --auto-approve
```

<!--- BEGIN_TF_DOCS --->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.66.0 |
| <a name="requirement_helm"></a> [helm](#requirement\_helm) | >= 2.4.1 |
| <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) | >= 2.6.1 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.66.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_aws-eks-accelerator-for-terraform"></a> [aws-eks-accelerator-for-terraform](#module\_aws-eks-accelerator-for-terraform) | ../.. | n/a |
| <a name="module_aws_vpc"></a> [aws\_vpc](#module\_aws\_vpc) | terraform-aws-modules/vpc/aws | v3.2.0 |
| <a name="module_kubernetes-addons"></a> [kubernetes-addons](#module\_kubernetes-addons) | ../../modules/kubernetes-addons | n/a |

## Resources

| Name | Type |
|------|------|
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_eks_cluster.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source |
| [aws_eks_cluster_auth.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster_auth) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |

## Inputs

No inputs.

## Outputs

No outputs.

<!--- END_TF_DOCS --->
Loading

0 comments on commit acd5ffa

Please sign in to comment.