:_mod-docs-content-type: ASSEMBLY
[id=“cloud-experts-using-aws-ack]
= Tutorial: Using AWS Controllers for Kubernetes on {product-title}
include::_attributes/attributes-openshift-dedicated.adoc[]
:context: cloud-experts-using-aws-ack

toc::[]

//Mobb content metadata
//Brought into ROSA product docs 2023-09-21
//---
//date: '2022-06-02'
//title: Using AWS Controllers for Kubernetes (ACK) on ROSA
//weight: 1
//tags: ["AWS", "ROSA"]
//authors:
//  - Paul Czarkowski
//  - Connor Wooley
//---

link:https://aws-controllers-k8s.github.io/community/[AWS Controllers for Kubernetes] (ACK) lets you define and use AWS service resources directly from {product-title}. With ACK, you can take advantage of AWS-managed services for your applications without needing to define resources outside of the cluster or run services that provide supporting capabilities such as databases or message queues within the cluster.

You can install various ACK Operators directly from OperatorHub. This makes it easy to get started and use the Operators with your applications. This controller is a component of the AWS Controller for Kubernetes project, which is currently in developer preview.

Use this tutorial to deploy the ACK S3 Operator. You can also adapt it for any other ACK Operator in the OperatorHub of your cluster.

[id="cloud-experts-using-aws-ack-prerequisites"]
== Prerequisites

* A {product-title} cluster
* A user account with `cluster-admin` privileges
* The OpenShift CLI (`oc`)
* The Amazon Web Services (AWS) CLI (`aws`)

[id="cloud-experts-using-aws-ack-environment-setup"]
== Setting up your environment

. Configure the following environment variables, changing the cluster name to suit your cluster:
+
[source,terminal]
----
$ export CLUSTER_NAME=$(oc get infrastructure cluster -o=jsonpath="{.status.infrastructureName}"  | sed 's/-[a-z0-9]\{5\}$//')
$ export REGION=$(rosa describe cluster -c ${ROSA_CLUSTER_NAME} --output json | jq -r .region.id)
$ export OIDC_ENDPOINT=$(oc get authentication.config.openshift.io cluster -o json | jq -r .spec.serviceAccountIssuer | sed  's|^https://||')
$ export AWS_ACCOUNT_ID=`aws sts get-caller-identity --query Account --output text`
$ export ACK_SERVICE=s3
$ export ACK_SERVICE_ACCOUNT=ack-${ACK_SERVICE}-controller
$ export POLICY_ARN=arn:aws:iam::aws:policy/AmazonS3FullAccess
$ export AWS_PAGER=""
$ export SCRATCH="/tmp/${ROSA_CLUSTER_NAME}/ack"
$ mkdir -p ${SCRATCH}
----
. Ensure all fields output correctly before moving to the next section:
+
[source,terminal]
----
$ echo "Cluster: ${ROSA_CLUSTER_NAME}, Region: ${REGION}, OIDC Endpoint: ${OIDC_ENDPOINT}, AWS Account ID: ${AWS_ACCOUNT_ID}"
----

[id="cloud-experts-using-aws-ack-prep-aws"]
== Preparing your AWS Account

. Create an AWS Identity Access Management (IAM) trust policy for the ACK Operator:
+
[source,terminal]
----
$ cat <<EOF > "${SCRATCH}/trust-policy.json"
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Condition": {
   "StringEquals" : {
     "${OIDC_ENDPOINT}:sub": "system:serviceaccount:ack-system:${ACK_SERVICE_ACCOUNT}"
   }
 },
 "Principal": {
   "Federated": "arn:aws:iam::$AWS_ACCOUNT_ID:oidc-provider/${OIDC_ENDPOINT}"
 },
 "Action": "sts:AssumeRoleWithWebIdentity"
 }
 ]
}
EOF
----
+
. Create an AWS IAM role for the ACK Operator to assume with the `AmazonS3FullAccess` policy attached:
+
[NOTE]
====
You can find the recommended policy in each project's GitHub repository, for example https://github.com/aws-controllers-k8s/s3-controller/blob/main/config/iam/recommended-policy-arn.
====
+
[source,terminal]
----
$ ROLE_ARN=$(aws iam create-role --role-name "ack-${ACK_SERVICE}-controller" \
   --assume-role-policy-document "file://${SCRATCH}/trust-policy.json" \
   --query Role.Arn --output text)
$ echo $ROLE_ARN

$ aws iam attach-role-policy --role-name "ack-${ACK_SERVICE}-controller" \
     --policy-arn ${POLICY_ARN}
----

[id="cloud-experts-using-aws-ack-install-ack"]
== Installing the ACK S3 Controller

. Create a project to install the ACK S3 Operator into:
+
[source,terminal]
----
$ oc new-project ack-system
----
+
. Create a file with the ACK S3 Operator configuration:
+
[NOTE]
====
`ACK_WATCH_NAMESPACE` is purposefully left blank so the controller can properly watch all namespaces in the cluster.
====
+
[source,terminal]
----
$ cat << EOF  "${SCRATCH}/config.txt"
ACK_ENABLE_DEVELOPMENT_LOGGING=true
ACK_LOG_LEVEL=debug
ACK_WATCH_NAMESPACE=
AWS_REGION=${REGION}
AWS_ENDPOINT_URL=
ACK_RESOURCE_TAGS=${CLUSTER_NAME}
ENABLE_LEADER_ELECTION=true
LEADER_ELECTION_NAMESPACE=
RECONCILE_DEFAULT_MAX_CONCURRENT_SYNCS=1
FEATURE_FLAGS=
FEATURE_GATES=
EOF
----
+
. Use the file from the previous step to create a ConfigMap:
+
[source,terminal]
----
$ oc -n ack-system create configmap \
  --from-env-file=${SCRATCH}/config.txt ack-${ACK_SERVICE}-user-config
----
+
. Install the ACK S3 Operator from OperatorHub:
+
[source,terminal]
----
$ cat << EOF | oc apply -f -
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: ack-${ACK_SERVICE}-controller
  namespace: ack-system
spec:
  upgradeStrategy: Default
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: ack-${ACK_SERVICE}-controller
  namespace: ack-system
spec:
  channel: alpha
  installPlanApproval: Automatic
  name: ack-${ACK_SERVICE}-controller
  source: community-operators
  sourceNamespace: openshift-marketplace
EOF
----
+
. Annotate the ACK S3 Operator service account with the AWS IAM role to assume and restart the deployment:
+
[source,terminal]
----
$ oc -n ack-system annotate serviceaccount ${ACK_SERVICE_ACCOUNT} \
  eks.amazonaws.com/role-arn=${ROLE_ARN} && \
  oc -n ack-system rollout restart deployment ack-${ACK_SERVICE}-controller
----
+
. Verify that the ACK S3 Operator is running:
+
[source,terminal]
----
$ oc -n ack-system get pods
----
.Example output
+
[source,text]
----
NAME                                 READY   STATUS    RESTARTS   AGE
ack-s3-controller-585f6775db-s4lfz   1/1     Running   0          51s
----

[id="cloud-experts-using-aws-ack-valid-deploy"]
== Validating the deployment

. Deploy an S3 bucket resource:
+
[source,terminal]
----
$ cat << EOF | oc apply -f -
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
   name: ${CLUSTER-NAME}-bucket
   namespace: ack-system
spec:
   name: ${CLUSTER-NAME}-bucket
EOF
----
+
. Verify the S3 bucket was created in AWS:
+
[source,terminal]
----
$ aws s3 ls | grep ${CLUSTER_NAME}-bucket
----
+
.Example output
[source,text]
----
2023-10-04 14:51:45 mrmc-test-maz-bucket
----

[id="cloud-experts-using-aws-ack-clean-up"]
== Cleaning up

. Delete the S3 bucket resource:
+
[source,terminal]
----
$ oc -n ack-system delete bucket.s3.services.k8s.aws/${CLUSTER-NAME}-bucket
----
+
. Delete the ACK S3 Operator and the AWS IAM roles:
+
[source,terminal]
----
$ oc -n ack-system delete subscription ack-${ACK_SERVICE}-controller
$ aws iam detach-role-policy \
  --role-name "ack-${ACK_SERVICE}-controller" \
  --policy-arn ${POLICY_ARN}
$ aws iam delete-role \
  --role-name "ack-${ACK_SERVICE}-controller"
----
+
. Delete the `ack-system` project:
+
[source,terminal]
----
$ oc delete project ack-system
----
