# Part 3: Blueprint

## What Will You Do

In this part of the self-paced exercise, you will create a custom cluster blueprint with a [Amazon CloudWatch Agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html) add-on, based on declarative specifications.

---

## Step 1: Create Repository

In this step, you will create a repository in your project so that the controller can retrieve the Helm charts automatically.

- Open Terminal (on macOS/Linux) or Command Prompt (Windows) and navigate to the folder where you forked the Git repository
- Navigate to the folder "/getstarted/cloudwatch/repository"

The "cloudwatch-repository.yaml" file contains the declarative specification for the repository. In this case, the specification is of type "Helm Repository" and the "endpoint" is pointing to the AWS Github repository that includes the CloudWatch Helm chart.

```yaml
apiVersion: config.rafay.dev/v2
kind: Repository
metadata:
  name: cloudwatch-repo
spec:
  repositoryType: HelmRepository
  endpoint:  https://aws.github.io/eks-charts
  credentialType: CredentialTypeNotSet
```

Type the command below

```bash
rctl create repository -f cloudwatch-repository.yaml
```

If you did not encounter any errors, you can optionally verify if everything was created correctly on the controller.

- Navigate to the "defaultproject" project in your Org
- Select Integrations -> Repositories

---

## Step 2: Create Namespace

In this step, you will create a namespace for the Cloudwatch agent. The "cloudwatch-namespace.yaml" file contains the declarative specification.

The following items may need to be updated/customized if you made changes to these or used alternate names.

- value: cloudwatch-cluster

```yaml
kind: ManagedNamespace
apiVersion: config.rafay.dev/v2
metadata:
  name: amazon-cloudwatch
  description: namespace for Amazon Cloudwatch
  labels:
  annotations:
spec:
  type: RafayWizard
  resourceQuota:
  placement:
    placementType: ClusterSpecific
    clusterLabels:
    - key: rafay.dev/clusterName
      value: cloudwatch-cluster
```

- Open Terminal (on macOS/Linux) or Command Prompt (Windows) and navigate to the folder where you forked the Git repository
- Navigate to the folder "/getstarted/cloudwatch/namespace"
- Type the command below

```bash
rctl create namespace -f cloudwatch-namespace.yaml
```

If you did not encounter any errors, you can optionally verify if everything was created correctly on the controller.

- Navigate to the "defaultproject" project in your Org
- Select Infrastructure -> Namespaces
- You should see a namespace called "amazon-cloudwatch"

---

## Step 3: IRSA

In this step, you will create an IRSA so that the CloudWatch pods on the EKS cluster will have the necessary permissions. In AWS, it is a recommended best practice to use IAM roles for service accounts (IRSA) to access AWS services outside the EKS cluster because of the following benefits:

| Benefit | Description |
| --- | --- |
| Least Privilege | No longer need to provide extended permissions to the node IAM role so that pods on that node can call AWS APIs. You can scope IAM permissions to a service account, and only pods that use that service account have access to those permissions. This feature also eliminates the need for third-party solutions such as kiam or kube2iam. |
| Credential Isolation | A container can only retrieve credentials for the IAM role that is associated with the service account to which it belongs. A container never has access to credentials that are intended for another container that belongs to another pod. |
| Auditability | Access and event logging is available through CloudTrail to help ensure retrospective auditing. |

---

### Create IRSA

In the example below, the EKS cluster's name is "cloudwatch-cluster" and the IRSA name is "cloudwatch-irsa".

```bash
rctl create iam-service-account cloudwatch-cluster --name cloudwatch-irsa --namespace amazon-cloudwatch --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
```

---

### Verify IRSA

Creation of the IRSA can take a few seconds. You can verify the status of the IRSA by using RCTL.

```bash
rctl get iam-service-account cloudwatch-cluster --namespace amazon-cloudwatch
```

```json
[{"metadata":{"name":"cloudwatch-irsa","namespace":"amazon-cloudwatch"},"attachPolicyARNs":["arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"]}]
```

You can also verify that the k8s service account was created in the EKS cluster in the "amazon-cloudwatch" namespace.

- Click on the Zero Trust Kubectl Shell on the web console.

```bash
kubectl get sa --namespace amazon-cloudwatch
```

```plaintext
NAME              SECRETS   AGE
cloudwatch-irsa   1         2m41s
default           1         2m41s
```

As you can see in this example, the "cloudwatch-irsa" service account was successfully created in the "amazon-cloudwatch" namespace.

---

## Step 4: Create Addon

In this step, you will create a custom addon for the Cloudwatch Agent. The "cloudwatch-addon.yaml" file contains the declarative specification.

If you plan to use a different name for the cluster or a different IRSA name, you must update the "custom-values.yaml" file located in the folder "/getstarted/cloudwatch/addon" with the name of the cluster.

The following details are used to build the declarative specification.

- "v1" because this is our first version
- The addon is part of the "defaultproject"
- Name of addon is "cloudwatch-addon"
- The addon will be deployed to a namespace called "amazon-cloudwatch"
- You will be using a custom "custom-values.yaml as an override which is located in the folder "/getstarted/cloudwatch/addon"
- The "aws-cloudwatch-metrics" chart will be used from the previously created repository named "cloudwatch-repo"

The following items may need to be updated/customized if you made changes to these or used alternate names.

- repository_ref: "cloudwatch-repo"

```yaml
kind: AddonVersion
metadata:
  name: v1
  project: defaultproject
spec:
  addon: cloudwatch-addon
  namespace: amazon-cloudwatch
  template:
    type: Helm3
    valuesFile: custom-values.yaml
    repository_ref: cloudwatch-repo
    repo_artifact_meta:
      helm:
       chartName: aws-cloudwatch-metrics
```

- Open Terminal (on macOS/Linux) or Command Prompt (Windows) and navigate to the folder where you forked the Git repository
- Navigate to the folder "/getstarted/cloudwatch/addon"
- Type the command below

```bash
rctl create addon version -f cloudwatch-addon.yaml
```

If you did not encounter any errors, you can optionally verify if everything was created correctly on the controller.

- Navigate to the "defaultproject" project in your Org
- Select Infrastructure -> Addons
- You should see an addon called "cloudwatch-addon"

---

## Step 5: Create Blueprint

In this step, you will create a custom cluster blueprint with the CloudWatch addon. The "cloudwatch-blueprint.yaml" file contains the declarative specification.

- Open Terminal (on macOS/Linux) or Command Prompt (Windows) and navigate to the folder where you forked the Git repository
- Navigate to the folder "/getstarted/cloudwatch/blueprint"

The following items may need to be updated/customized if you made changes to these or used alternate names.

- project: "defaultproject"

```yaml
kind: Blueprint
metadata:
  # blueprint name
  name: cloudwatch-blueprint
  #project name
  project: defaultproject
```

- Type the command below

```bash
rctl create blueprint -f cloudwatch-blueprint.yaml
```

If you did not encounter any errors, you can optionally verify if everything was created correctly on the controller.

- Navigate to the "defaultproject" project in your Org
- Select Infrastructure -> Blueprint
- You should see a blueprint called "cloudwatch-blueprint"

---

### New Version

Although we have a custom blueprint, we have not provided any details on what it comprises. In this step, you will create and add a new version to the custom blueprint. The YAML below is a declarative spec for the new version.

The following items may need to be updated/customized if you made changes to these or used alternate names.

- project: "defaultproject"
- blueprint: "cloudwatch-blueprint"
- name: "cloudwatch-addon"
- version: "v1"

```yaml
kind: BlueprintVersion
metadata:
  name: v1
  project: defaultproject
  description: Amazon CloudWatch Agent
spec:
  blueprint: cloudwatch-blueprint
  baseSystemBlueprint: default
  baseSystemBlueprintVersion: ""
  addons:
    - name: cloudwatch-addon
      version: v1
  # cluster-scoped or namespace-scoped
  pspScope: cluster-scoped
  rafayIngress: true
  rafayMonitoringAndAlerting: false
  kubevirt: false
  # BlockAndNotify or DetectAndNotify
  driftAction: BlockAndNotify
```

- Type the command below to add a new version

```bash
rctl create blueprint version -f cloudwatch-blueprint-v1.yaml
```

If you did not encounter any errors, you can optionally verify if everything was created correctly on the controller.

- Navigate to the "defaultproject" project in your Org
- Select Infrastructure -> Blueprint
- Click on the "cloudwatch-blueprint" custom cluster blueprint

---

## Step 6: Apply Blueprint

In this step, you will apply the newly created custom cluster blueprint to the previously provisioned EKS cluster. The blueprint contains the CloudWatch Agent addon.

```bash
rctl update cluster cloudwatch-cluster --blueprint cloudwatch-blueprint --blueprint-version v1
```

---

## Step 7: Verify CloudWatch Agent

Now, let us verify the CloudWatch agent resources are operational on the EKS cluster

- Click on the kubectl link and type the following command

```bash
kubectl get pod -n amazon-cloudwatch
```

You should see something like the following

```plaintext
NAME                     READY   STATUS    RESTARTS   AGE
cloudwatch-addon-aws-cloudwatch-metrics-crld5   1/1     Running   0          4m51s
cloudwatch-addon-aws-cloudwatch-metrics-q9xnw   1/1     Running   0          4m51s
```

---

## Step 8: Verify Metrics

Verify that the agents are connected to CloudWatch and reporting data.

- In the AWS console, go to CloudWatch -> Insights -> Container Insights and search for the cluster "Cloudwatch-cluster"
- View the metrics for the cluster in Amazon CloudWatch

---

## Recap

Congratulations! At this point, you have successfully configured and provisioned an Amazon EKS cluster with the Amazon CloudWatch agent in your AWS account using the RCTL CLI.

Note that you can also reuse this cluster blueprint for as many clusters as you require in this project and also share the blueprint with other projects.

---
