

# Tutorial: Connect from a containerized application hosted on Amazon Elastic Kubernetes Service
<a name="EKS-tutorial"></a>

This tutorial walks you through the steps required to set up an Amazon Elastic Kubernetes Service (Amazon EKS) cluster to host a containerized application that connects to Amazon Keyspaces using SigV4 authentication.

Amazon EKS is a managed service that eliminates the need to install, operate, and maintain your own Kubernetes control plane. [Kubernetes](https://kubernetes.io/docs/concepts/overview/) is an open-source system that automates the management, scaling, and deployment of containerized applications.

The tutorial provides step-by-step guidance to configure, build, and deploy a containerized Java application to Amazon EKS. In the last step you run the application to write data to an Amazon Keyspaces table.

**Topics**
+ [Prerequisites for connecting from Amazon EKS to Amazon Keyspaces](EKS-tutorial-prerequisites.md)
+ [Step 1: Configure the Amazon EKS cluster and setup IAM permissions](EKS-tutorial-step1.md)
+ [Step 2: Configure the application](EKS-tutorial-step2.md)
+ [Step 3: Create the application image and upload the Docker file to your Amazon ECR repository](EKS-tutorial-step3.md)
+ [Step 4: Deploy the application to Amazon EKS and write data to your table](EKS-tutorial-step4.md)
+ [Step 5: (Optional) Cleanup](EKS-tutorial-step5.md)

# Prerequisites for connecting from Amazon EKS to Amazon Keyspaces
<a name="EKS-tutorial-prerequisites"></a>

**Create the following AWS resources before you can begin with the tutorial**

1. Before you start this tutorial, follow the AWS setup instructions in [Accessing Amazon Keyspaces (for Apache Cassandra)](accessing.md). These steps include signing up for AWS and creating an AWS Identity and Access Management (IAM) principal with access to Amazon Keyspaces. 

1. Create an Amazon Keyspaces keyspace with the name `aws` and a table with the name `user` that you can write to from the containerized application running in Amazon EKS later in this tutorial. You can do this either with the AWS CLI or using `cqlsh`.

------
#### [ AWS CLI ]

   ```
   aws keyspaces create-keyspace --keyspace-name 'aws'
   ```

   To confirm that the keyspace was created, you can use the following command.

   ```
   aws keyspaces list-keyspaces
   ```

   To create the table, you can use the following command.

   ```
   aws keyspaces create-table --keyspace-name 'aws' --table-name 'user' --schema-definition 'allColumns=[
               {name=username,type=text}, {name=fname,type=text},{name=last_update_date,type=timestamp},{name=lname,type=text}],
               partitionKeys=[{name=username}]'
   ```

   To confirm that your table was created, you can use the following command.

   ```
   aws keyspaces list-tables --keyspace-name 'aws'
   ```

   For more information, see [create keyspace](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/keyspaces/create-keyspace.html) and [create table](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/keyspaces/create-table.html) in the *AWS CLI Command Reference*.

------
#### [ cqlsh ]

   ```
   CREATE KEYSPACE aws WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}  AND durable_writes = true;
   CREATE TABLE aws.user (
       username text PRIMARY KEY,
       fname text,
       last_update_date timestamp,
       lname text
   );
   ```

   To verify that your table was created, you can use the following statement.

   ```
   SELECT * FROM system_schema.tables WHERE keyspace_name = "aws";
   ```

   Your table should be listed in the output of this statement. Note that there can be a delay until the table is created. For more information, see [CREATE TABLE](cql.ddl.table.md#cql.ddl.table.create).

------

1. Create an Amazon EKS cluster with a **Fargate - Linux ** node type. Fargate is a serverless compute engine that lets you deploy Kubernetes Pods without managing Amazon Amazon EC2 instances. To follow this tutorial without having to update the cluster name in all the example commands, create a cluster with the name `my-eks-cluster` following the instructions at [Getting started with Amazon EKS – `eksctl`](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html) in the *Amazon EKS User Guide*. When your cluster is created, verify that your nodes and the two default Pods are running and healthy. You can do so with the following command.

   ```
   kubectl get pods -A -o wide
   ```

   You should see something similar to this output.

   ```
   NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE   IP          NODE                                                NOMINATED NODE   READINESS GATES
   kube-system   coredns-1234567890-abcde   1/1     Running   0          18m   192.0.2.0   fargate-ip-192-0-2-0.region-code.compute.internal   <none>           <none>
   kube-system   coredns-1234567890-12345   1/1     Running   0          18m   192.0.2.1   fargate-ip-192-0-2-1.region-code.compute.internal   <none>           <none>
   ```

1. Install Docker. For instructions on how to install Docker on an Amazon EC2 instance, see [Install Docker](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#getting-started-cli-prereqs) in the Amazon Elastic Container Registry User Guide. 

   Docker is available for many different operating systems, including most modern Linux distributions, like Ubuntu, and even macOS and Windows. For more information about how to install Docker on your particular operating system, go to the [Docker installation guide](https://docs.docker.com/engine/install/#installation). 

1. Create an Amazon ECR repository. Amazon ECR is an AWS managed container image registry service that you can use with your preferred CLI to push, pull, and manage Docker images. For more information about Amazon ECR repositories, see the [Amazon Elastic Container Registry User Guide](https://docs.aws.amazon.com/AmazonECR/latest/userguide/). You can use the following command to create a repository with the name `my-ecr-repository`.

   ```
   aws ecr create-repository --repository-name my-ecr-repository
   ```

After completing the prerequisite steps, proceed to [Step 1: Configure the Amazon EKS cluster and setup IAM permissions](EKS-tutorial-step1.md).

# Step 1: Configure the Amazon EKS cluster and setup IAM permissions
<a name="EKS-tutorial-step1"></a>

**Configure the Amazon EKS cluster and create the IAM resources that are required to allow an Amazon EKS service account to connect to your Amazon Keyspaces table**

1. Create an Open ID Connect (OIDC) provider for the Amazon EKS cluster. This is needed to use IAM roles for service accounts. For more information about OIDC providers and how to create them, see [ Creating an IAM OIDC provider for your cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html) in the *Amazon EKS User Guide*.

   1. Create an IAM OIDC identity provider for your cluster with the following command. This example assumes that your cluster name is `my-eks-cluster`. If you have a cluster with a different name, remember to update the name in all future commands.

      ```
      eksctl utils associate-iam-oidc-provider --cluster my-eks-cluster --approve 
      ```

   1. Confirm that the OIDC identity provider has been registered with IAM with the following command.

      ```
      aws iam list-open-id-connect-providers --region us-east-1
      ```

      The output should look similar to this. Take note of the OIDC's Amazon Resource Name (ARN), you need it in the next step when you create a trust policy for the service account.

      ```
      {
          "OpenIDConnectProviderList": [
              ..
              {
                  "Arn": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
              }
          ]
      }
      ```

1. Create a service account for the Amazon EKS cluster. Service accounts provide an identity for processes that run in a *Pod*. A Pod is the smallest and simplest Kubernetes object that you can use to deploy a containerized application. Next, create an IAM role that the service account can assume to obtain permissions to resources. You can access any AWS service from a Pod that has been configured to use a service account that can assume an IAM role with access permissions to that service.

   1. Create a new namespace for the service account. A namespace helps to isolate cluster resources created for this tutorial. You can create a new namespace using the following command.

      ```
      kubectl create namespace my-eks-namespace
      ```

   1. To use a custom namespace, you have to associate it with a Fargate profile. The following code is an example of this.

      ```
      eksctl create fargateprofile \
          --cluster my-eks-cluster \
          --name my-fargate-profile \
          --namespace my-eks-namespace \
          --labels *=*
      ```

   1. Create a service account with the name `my-eks-serviceaccount` in the namespace `my-eks-namespace` for your Amazon EKS cluster by using the following command.

      ```
      cat >my-serviceaccount.yaml <<EOF
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: my-eks-serviceaccount
        namespace: my-eks-namespace
      EOF
      kubectl apply -f my-serviceaccount.yaml
      ```

   1. Run the following command to create a trust policy file that instructs the IAM role to trust your service account. This trust relationship is required before a principal can assume a role. You need to make the following edits to the file:
      + For the `Principal`, enter the ARN that IAM returned to the `list-open-id-connect-providers` command. The ARN contains your account number and Region.
      + In the `condition` statement, replace the AWS Region and the OIDC id.
      + Confirm that the service account name and namespace are correct.

      You need to attach the trust policy file in the next step when you create the IAM role.

      ```
      cat >trust-relationship.json <<EOF
      {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
                  },
                  "Action": "sts:AssumeRoleWithWebIdentity",
                  "Condition": {
                      "StringEquals": {
                          "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:my-eks-namespace:my-eks-serviceaccount",
                          "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
                      }
                  }
              }
          ]
      }
      EOF
      ```

      Optional: You can also add multiple entries in the `StringEquals` or `StringLike` conditions to allow multiple service accounts or namespaces to assume the role. To allow your service account to assume an IAM role in a different AWS account, see [ Cross-account IAM permissions](https://docs.aws.amazon.com/eks/latest/userguide/cross-account-access.html) in the *Amazon EKS User Guide*.

1. Create an IAM role with the name `my-iam-role` for the Amazon EKS service account to assume. Attach the trust policy file created in the last step to the role. The trust policy specifies the service account and OIDC provider that the IAM role can trust. 

   ```
   aws iam create-role --role-name my-iam-role --assume-role-policy-document file://trust-relationship.json --description "EKS service account role"
   ```

1. Assign the IAM role permissions to Amazon Keyspaces by attaching an access policy. 

   1. Attach an access policy to define the actions the IAM role can perform on specific Amazon Keyspaces resources. For this tutorial we use the AWS managed policy `AmazonKeyspacesFullAccess`, because our application is going to write data to your Amazon Keyspaces table. As a best practise however, it's recommended to create custom access policies that implement the least privileges principle. For more information, see [How Amazon Keyspaces works with IAM](security_iam_service-with-iam.md).

      ```
      aws iam attach-role-policy --role-name my-iam-role --policy-arn=arn:aws:iam::aws:policy/AmazonKeyspacesFullAccess
      ```

      Confirm that the policy was successfully attached to the IAM role with the following statement.

      ```
      aws iam list-attached-role-policies --role-name my-iam-role
      ```

      The output should look like this.

      ```
      {
          "AttachedPolicies": [
              {
                  "PolicyName": "AmazonKeyspacesFullAccess",
                  "PolicyArn": "arn:aws:iam::aws:policy/AmazonKeyspacesFullAccess"
              }
          ]
      }
      ```

   1. Annotate the service account with the Amazon Resource Name (ARN) of the IAM role it can assume. Make sure to update the role ARN with your account ID.

      ```
      kubectl annotate serviceaccount -n my-eks-namespace my-eks-serviceaccount eks.amazonaws.com/role-arn=arn:aws:iam::111122223333:role/my-iam-role
      ```

1. Confirm that the IAM role and the service account are correctly configured.

   1. Confirm that the IAM role's trust policy is correctly configured with the following statement.

      ```
      aws iam get-role --role-name my-iam-role --query Role.AssumeRolePolicyDocument
      ```

      The output should look similar to this.

      ```
      {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
                  },
                  "Action": "sts:AssumeRoleWithWebIdentity",
                  "Condition": {
                      "StringEquals": {
                          "oidc.eks.us-east-1/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com",
                          "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:my-eks-namespace:my-eks-serviceaccount"
                      }
                  }
              }
          ]
      }
      ```

   1. Confirm that the Amazon EKS service account is annotated with the IAM role.

      ```
      kubectl describe serviceaccount my-eks-serviceaccount -n my-eks-namespace
      ```

      The output should look similar to this.

      ```
      Name: my-eks-serviceaccount 
      Namespace:my-eks-namespace
      Labels: <none>
      Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/my-iam-role 
      Image pull secrets: <none> 
      Mountable secrets: <none> 
      Tokens: <none> 
      [...]
      ```

After you created the Amazon EKS service account, the IAM role, and configured the required relationships and permissions, proceed to [Step 2: Configure the application](EKS-tutorial-step2.md).

# Step 2: Configure the application
<a name="EKS-tutorial-step2"></a>

In this step you build your application that connects to Amazon Keyspaces using the SigV4 plugin. You can view and download the example Java application from the Amazon Keyspaces example code repo on [Github](https://github.com/aws-samples/amazon-keyspaces-examples/tree/main/java/datastax-v4/eks). Or you can follow along using your own application, making sure to complete all configuration steps.

**Configure your application and add the required dependencies.**

1. You can download the example Java application by cloning the Github repository using the following command.

   ```
   git clone https://github.com/aws-samples/amazon-keyspaces-examples.git
   ```

1. After downloading the Github repo, unzip the downloaded file and navigate to the `resources` directory to the `application.conf` file.

   1. **Application configuration**

      In this step you configure the SigV4 authentication plugin. You can use the following example in your application. If you haven't already done so, you need to generate your IAM access keys (an access key ID and a secret access key) and save them in your AWS config file or as environment variables. For detailed instructions, see [Credentials required by the AWS CLI, the AWS SDK, or the Amazon Keyspaces SigV4 plugin for Cassandra client drivers](SigV4_credentials.md). Update the AWS Region and the service endpoint for Amazon Keyspaces as needed. For more service endpoints, see [Service endpoints for Amazon Keyspaces](programmatic.endpoints.md). Replace the truststore location, truststore name, and the truststore password with your own.

      ```
      datastax-java-driver {
        basic.contact-points = ["cassandra.us-east-1.amazonaws.com:9142"]
        basic.load-balancing-policy.local-datacenter = "us-east-1"
        advanced.auth-provider {
          class = software.aws.mcs.auth.SigV4AuthProvider
          aws-region = "us-east-1"
        }
        advanced.ssl-engine-factory {
          class = DefaultSslEngineFactory
          truststore-path = "truststore_locationtruststore_name.jks"
          truststore-password = "truststore_password;"
        }
      }
      ```

   1. **Add the STS module dependency.**

      This adds the ability to use a `WebIdentityTokenCredentialsProvider` that returns the AWS credentials that the application needs to provide so that the service account can assume the IAM role. You can do this based on the following example.

      ```
              <dependency>
                  <groupId>com.amazonaws</groupId>
                  <artifactId>aws-java-sdk-sts</artifactId>
                  <version>1.11.717</version> 
              </dependency>
      ```

   1. **Add the SigV4 dependency.**

       This package implements the SigV4 authentication plugin that is needed to authenticate to Amazon Keyspaces

      ```
              <dependency>
                  <groupId>software.aws.mcs</groupId>
                  <artifactId>aws-sigv4-auth-cassandra-java-driver-plugin</artifactId>
                  <version>4.0.3</version> 
              </dependency>
      ```

1. **Add a logging dependency.**

    Without logs, troubleshooting connection issues is impossible. In this tutorial, we use `slf4j` as the logging framework, and use `logback.xml` to store the log output. We set the logging level to `debug` to establish the connection. You can use the following example to add the dependency.

   ```
           <dependency>
               <groupId>org.slf4j</groupId>
               <artifactId>slf4j-api</artifactId>
               <version>2.0.5</version> 
           </dependency>
   ```

   You can use the following code snippet to configure the logging.

   ```
   <configuration>
       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
           
           <encoder>
               <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
           </encoder>
       </appender>
   
       <root level="debug">
           <appender-ref ref="STDOUT" />
       </rootv
   </configuration>
   ```
**Note**  
The `debug` level is needed to investigate connection failures. After you have successfully connected to Amazon Keyspaces from your application, you can change the logging level to `info` or `warning` as needed. 

# Step 3: Create the application image and upload the Docker file to your Amazon ECR repository
<a name="EKS-tutorial-step3"></a>

In this step, you compile the example application, build a Docker image, and push the image to your Amazon ECR repository.

**Build your application, build a Docker image, and submit it to Amazon Elastic Container Registry**

1. Set environment variables for the build that define your AWS Region. Replace the Regions in the examples with your own.

   ```
   export CASSANDRA_HOST=cassandra.us-east-1.amazonaws.com:9142
   export CASSANDRA_DC=us-east-1
   ```

1. Compile your application with Apache Maven version 3.6.3 or higher using the following command.

   ```
   mvn clean install
   ```

   This creates a `JAR` file with all dependencies included in the `target` directory.

1. Retrieve your ECR repository URI that's needed for the next step with the following command. Make sure to update the Region to the one you've been using.

   ```
   aws ecr describe-repositories --region us-east-1
   ```

   The output should look like in the following example.

   ```
   "repositories": [
    {
    "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/my-ecr-repository",
    "registryId": "111122223333",
    "repositoryName": "my-ecr-repository",
    "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/my-ecr-repository",
    "createdAt": "2023-11-02T03:46:34+00:00",
    "imageTagMutability": "MUTABLE",
    "imageScanningConfiguration": {
    "scanOnPush": false
    },
    "encryptionConfiguration": {
    "encryptionType": "AES256"
    }
    },
   ```

1. From the application's root directory build the Docker image using the repository URI from the last step. Modify the Docker file as needed. In the build command, make sure to replace your account ID and set the AWS Region to the Region where the Amazon ECR repository `my-ecr-repository` is located. 

   ```
   docker build -t 111122223333.dkr.ecr.us-east-1.amazonaws.com/my-ecr-repository:latest .
   ```

1. Retrieve an authentication token to push the Docker image to Amazon ECR. You can do so with the following command.

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. First, check for existing images in your Amazon ECR repository. You can use the following command.

   ```
   aws ecr describe-images --repository-name my-ecr-repository --region us-east-1
   ```

   Then, push the Docker image to the repo. You can use the following command.

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/my-ecr-repository:latest
   ```

# Step 4: Deploy the application to Amazon EKS and write data to your table
<a name="EKS-tutorial-step4"></a>

In this step of the tutorial, you configure the Amazon EKS deployment for your application, and confirm that the application is running and can connect to Amazon Keyspaces.

To deploy an application to Amazon EKS, you need to configure all relevant settings in a file called `deployment.yaml`. This file is then used by Amazon EKS to deploy the application. The metadata in the file should contain the following information:
+ **Application name**  the name of the application. For this tutorial, we use `my-keyspaces-app`.
+ **Kubernetes namespace**  the namespace of the Amazon EKS cluster. For this tutorial, we use `my-eks-namespace`.
+ **Amazon EKS service account name**  the name of the Amazon EKS service account. For this tutorial, we use `my-eks-serviceaccount`.
+ **image name**  the name of the application image. For this tutorial, we use `my-keyspaces-app`.
+ **Image URI**  the Docker image URI from Amazon ECR.
+  **AWS account ID**  your AWS account ID.
+ **IAM role ARN**  the ARN of the IAM role created for the service account to assume. For this tutorial, we use `my-iam-role`.
+ **AWS Region of the Amazon EKS cluster**  the AWS Region you created your Amazon EKS cluster in.

In this step, you deploy and run the application that connects to Amazon Keyspaces and writes data to the table.

1. Configure the `deployment.yaml` file. You need to replace the following values:
   + `name`
   + `namespace`
   + `serviceAccountName`
   + `image`
   + `AWS_ROLE_ARN value`
   + The AWS Region in `CASSANDRA_HOST`
   + `AWS_REGION`

   You can use the following file as an example.

   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: my-keyspaces-app
     namespace: my-eks-namespace
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: my-keyspaces-app
     template:
       metadata:
         labels:
           app: my-keyspaces-app
       spec:
         serviceAccountName: my-eks-serviceaccount
         containers:
         - name: my-keyspaces-app
           image: 111122223333.dkr.ecr.us-east-1.amazonaws.com/my-ecr-repository:latest
           ports:
           - containerPort: 8080
           env:
           - name: CASSANDRA_HOST
             value: "cassandra.us-east-1.amazonaws.com:9142"
           - name: CASSANDRA_DC
             value: "us-east-1"
           - name: AWS_WEB_IDENTITY_TOKEN_FILE
             value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
           - name: AWS_ROLE_ARN
             value: "arn:aws:iam::111122223333:role/my-iam-role"
           - name: AWS_REGION
             value: "us-east-1"
   ```

1. Deploy `deployment.yaml`.

   ```
   kubectl apply -f deployment.yaml
   ```

   The output should look like this.

   ```
   deployment.apps/my-keyspaces-app created
   ```

1. Check the status of the Pod in your namespace of the Amazon EKS cluster. 

   ```
   kubectl get pods -n my-eks-namespace
   ```

   The output should look similar to this example.

   ```
   NAME                    READY STATUS RESTARTS AGE
   my-keyspaces-app-123abcde4f-g5hij 1/1 Running 0 75s
   ```

   For more details, you can use the following command.

   ```
   kubectl describe pod my-keyspaces-app-123abcde4f-g5hij -n my-eks-namespace
   ```

   ```
   Name:                 my-keyspaces-app-123abcde4f-g5hij
   Namespace:            my-eks-namespace
   Priority:             2000001000
   Priority Class Name:  system-node-critical
   Service Account:      my-eks-serviceaccount
   Node:                 fargate-ip-192-168-102-209.ec2.internal/192.168.102.209
   Start Time:           Thu, 23 Nov 2023 12:15:43 +0000
   Labels:               app=my-keyspaces-app
                         eks.amazonaws.com/fargate-profile=my-fargate-profile
                         pod-template-hash=6c56fccc56
   Annotations:          CapacityProvisioned: 0.25vCPU 0.5GB
                         Logging: LoggingDisabled: LOGGING_CONFIGMAP_NOT_FOUND
   Status:               Running
   IP:                   192.168.102.209
   IPs:
     IP:           192.168.102.209
   Controlled By:  ReplicaSet/my-keyspaces-app-6c56fccc56
   Containers:
     my-keyspaces-app:
       Container ID:   containerd://41ff7811d33ae4bc398755800abcdc132335d51d74f218ba81da0700a6f8c67b
       Image:          111122223333.dkr.ecr.us-east-1.amazonaws.com/my_eks_repository:latest
       Image ID:       111122223333.dkr.ecr.us-east-1.amazonaws.com/my_eks_repository@sha256:fd3c6430fc5251661efce99741c72c1b4b03061474940200d0524b84a951439c
       Port:           8080/TCP
       Host Port:      0/TCP
       State:          Running
         Started:      Thu, 23 Nov 2023 12:15:19 +0000
         Finished:     Thu, 23 Nov 2023 12:16:17 +0000
       Ready:          True
       Restart Count:  1
       Environment:
         CASSANDRA_HOST:               cassandra.us-east-1.amazonaws.com:9142
         CASSANDRA_DC:                 us-east-1
         AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
         AWS_ROLE_ARN:                 arn:aws:iam::111122223333:role/my-iam-role
         AWS_REGION:                   us-east-1
         AWS_STS_REGIONAL_ENDPOINTS:   regional
       Mounts:
         /var/run/secrets/eks.amazonaws.com/serviceaccount from aws-iam-token (ro)
         /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-fssbf (ro)
   Conditions:
     Type              Status
     Initialized       True 
     Ready             True 
     ContainersReady   True 
     PodScheduled      True 
   Volumes:
     aws-iam-token:
       Type:                    Projected (a volume that contains injected data from multiple sources)
       TokenExpirationSeconds:  86400
     kube-api-access-fssbf:
       Type:                    Projected (a volume that contains injected data from multiple sources)
       TokenExpirationSeconds:  3607
       ConfigMapName:           kube-root-ca.crt
       ConfigMapOptional:       <nil>
       DownwardAPI:             true
   QoS Class:                   BestEffort
   Node-Selectors:              <none>
   Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                                node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
   Events:
     Type     Reason           Age                From               Message
     ----     ------           ----               ----               -------
     Warning  LoggingDisabled  2m13s              fargate-scheduler  Disabled logging because aws-logging configmap was not found. configmap "aws-logging" not found
     Normal   Scheduled        89s                fargate-scheduler  Successfully assigned my-eks-namespace/my-keyspaces-app-6c56fccc56-mgs2m to fargate-ip-192-168-102-209.ec2.internal
     Normal   Pulled           75s                kubelet            Successfully pulled image "111122223333.dkr.ecr.us-east-1.amazonaws.com/my_eks_repository:latest" in 13.027s (13.027s including waiting)
     Normal   Pulling          54s (x2 over 88s)  kubelet            Pulling image "111122223333.dkr.ecr.us-east-1.amazonaws.com/my_eks_repository:latest"
     Normal   Created          54s (x2 over 75s)  kubelet            Created container my-keyspaces-app
     Normal   Pulled           54s                kubelet            Successfully pulled image "111122223333.dkr.ecr.us-east-1.amazonaws.com/my_eks_repository:latest" in 222ms (222ms including waiting)
     Normal   Started          53s (x2 over 75s)  kubelet            Started container my-keyspaces-app
   ```

1. Check the Pod's logs to confirm that your application is running and can connect to your Amazon Keyspaces table. You can do so with the following command. Make sure to replace the name of your deployment.

   ```
   kubectl logs -f my-keyspaces-app-123abcde4f-g5hij -n my-eks-namespace
   ```

   You should be able to see application log entries confirming the connection to Amazon Keyspaces like in the example below.

   ```
   2:47:20.553 [s0-admin-0] DEBUG c.d.o.d.i.c.metadata.MetadataManager - [s0] Adding initial contact points [Node(endPoint=cassandra.us-east-1.amazonaws.com/1.222.333.44:9142, hostId=null, hashCode=e750d92)]
   22:47:20.562 [s0-admin-1] DEBUG c.d.o.d.i.c.c.ControlConnection - [s0] Initializing with event types [SCHEMA_CHANGE, STATUS_CHANGE, TOPOLOGY_CHANGE]
   22:47:20.564 [s0-admin-1] DEBUG c.d.o.d.i.core.context.EventBus - [s0] Registering com.datastax.oss.driver.internal.core.metadata.LoadBalancingPolicyWrapper$$Lambda$812/0x0000000801105e88@769afb95 for class com.datastax.oss.driver.internal.core.metadata.NodeStateEvent
   22:47:20.566 [s0-admin-1] DEBUG c.d.o.d.i.c.c.ControlConnection - [s0] Trying to establish a connection to Node(endPoint=cassandra.us-east-1.amazonaws.com/1.222.333.44:9142, hostId=null, hashCode=e750d92)
   ```

1. Run the following CQL query on your Amazon Keyspaces table to confirm that one row of data has been written to your table:

   ```
   SELECT * from aws.user;
   ```

   You should see the following output:

   ```
   fname    | lname | username | last_update_date 
   ----------+-------+----------+-----------------------------
   random    | k     | test     | 2023-12-07 13:58:31.57+0000
   ```

# Step 5: (Optional) Cleanup
<a name="EKS-tutorial-step5"></a>

Follow these steps to remove all the resources created in this tutorial.

**Remove the resources created in this tutorial**

1. Delete your deployment. You can use the following command to do so.

   ```
   kubectl delete deployment my-keyspaces-app -n my-eks-namespace
   ```

1. Delete the Amazon EKS cluster and all Pods contained in it. This also deletes related resources like the service account and OIDC identity provider. You can use the following command to do so.

   ```
   eksctl delete cluster --name my-eks-cluster --region us-east-1
   ```

1. Delete the IAM role used for the Amazon EKS service account with access permissions to Amazon Keyspaces. First, you have to remove the managed policy that is attached to the role.

   ```
   aws iam detach-role-policy --role-name my-iam-role --policy-arn arn:aws:iam::aws:policy/AmazonKeyspacesFullAccess
   ```

   Then you can delete the role using the following command.

   ```
   aws iam delete-role --role-name my-iam-role
   ```

   For more information, see [Deleting an IAM role (AWS CLI)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_manage_delete.html#roles-managingrole-deleting-cli) in the *IAM User Guide*. 

1. Delete the Amazon ECR repository including all the images stored in it. You can do so using the following command.

   ```
   aws ecr delete-repository \
         --repository-name my-ecr-repository \
         --force \
         --region us-east-1
   ```

   Note that the `force` flag is required to delete a repository that contains images. To delete your image first, you can do so using the following command. 

   ```
   aws ecr batch-delete-image \
         --repository-name my-ecr-repository \
         --image-ids imageTag=latest \
         --region us-east-1
   ```

   For more information, see [Delete an image](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-delete-image) in the Amazon Elastic Container Registry User Guide.

1. Delete the Amazon Keyspaces keyspace and table. Deleting the keyspace automatically deletes all tables in that keyspace. You can use one the following options to do so.

------
#### [ AWS CLI ]

   ```
   aws keyspaces delete-keyspace --keyspace-name 'aws'
   ```

   To confirm that the keyspace was deleted, you can use the following command.

   ```
   aws keyspaces list-keyspaces
   ```

   To delete the table first, you can use the following command.

   ```
   aws keyspaces delete-table --keyspace-name 'aws' --table-name 'user'
   ```

   To confirm that your table was deleted, you can use the following command.

   ```
   aws keyspaces list-tables --keyspace-name 'aws'
   ```

   For more information, see [delete keyspace](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/keyspaces/delete-keyspace.html) and [delete table](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/keyspaces/delete-table.html) in the *AWS CLI Command Reference*.

------
#### [ cqlsh ]

   ```
   DROP KEYSPACE IF EXISTS "aws";
   ```

   To verify that your keyspaces was deleted, you can use the following statement.

   ```
   SELECT * FROM system_schema.keyspaces ;
   ```

   Your keyspace should not be listed in the output of this statement. Note that there can be a delay until the keyspaces is deleted. For more information, see [DROP KEYSPACE](cql.ddl.keyspace.md#cql.ddl.keyspace.drop).

   To delete the table first, you can use the following command.

   ```
   DROP TABLE "aws.user"
   ```

   To confirm that your table was deleted, you can use the following command.

   ```
   SELECT * FROM system_schema.tables WHERE keyspace_name = "aws";
   ```

   Your table should not be listed in the output of this statement. Note that there can be a delay until the table is deleted. For more information, see [DROP TABLE](cql.ddl.table.md#cql.ddl.table.drop).

------