<jupyter_start><jupyter_text>EKS CSI FSX Lustre SetupAmazon FSx for Lustre is a high-performance file system optimized for deep learning workloads. FSx provides POSIX-compliant file system access to S3 for multiple readers and writers simultaneously.  The Amazon FSx for Lustre Container Storage Interface (CSI) driver provides a CSI interface that allows Amazon EKS clusters to manage the lifecycle of Amazon FSx for Lustre file systems.  * https://docs.aws.amazon.com/eks/latest/userguide/fsx-csi.html* https://github.com/kubernetes-sigs/aws-fsx-csi-driver<jupyter_code>import boto3
import json
from botocore.exceptions import ClientError

iam = boto3.client("iam")
sts = boto3.client("sts")
cfn = boto3.client("cloudformation")
eks = boto3.client("eks")

region = boto3.Session().region_name
cluster_name = "workshop"<jupyter_output><empty_output><jupyter_text>1. Install the FSx CSI Driver for Kubernetes  Create IAM PolicyCreate an IAM policy and service account that allows the driver to make calls to AWS APIs on your behalf.<jupyter_code>!pygmentize fsx/fsx-csi-driver.json
# !aws iam create-policy \
#     --policy-name Amazon_FSx_Lustre_CSI_Driver \
#     --policy-document file://fsx/fsx-csi-driver.json
with open("fsx/fsx-csi-driver.json") as json_file:
    data = json.load(json_file)
    policy = json.dumps(data)

try:
    response = iam.create_policy(PolicyName="Amazon_FSx_Lustre_CSI_Driver", PolicyDocument=policy)
    print("[OK] Policy created.")

except ClientError as e:
    if e.response["Error"]["Code"] == "EntityAlreadyExists":
        print("[OK] Policy already exists.")
    else:
        print("Error: %s" % e)
account_id = sts.get_caller_identity()["Account"]
csi_policy_arn = "arn:aws:iam::{}:policy/Amazon_FSx_Lustre_CSI_Driver".format(account_id)
print(csi_policy_arn)<jupyter_output><empty_output><jupyter_text>Create Kubernetes IAM Service AccountCreate a Kubernetes service account for the driver and attach the policy to the service account. Replacing the ARN of the policy with the ARN returned in the previous step.  _The next cell runs for about 10min. Please be patient._<jupyter_code>!eksctl create iamserviceaccount \
     --region $region \
     --name fsx-csi-controller-sa \
     --namespace kube-system \
     --cluster $cluster_name \
     --attach-policy-arn $csi_policy_arn \
     --approve
cf_stack_name = "eksctl-{}-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa".format(cluster_name)
print(cf_stack_name)
response = cfn.list_stack_resources(StackName=cf_stack_name)
print(response)
iam_role_name = response["StackResourceSummaries"][0]["PhysicalResourceId"]
print(iam_role_name)
iam_role_arn = iam.get_role(RoleName=iam_role_name)["Role"]["Arn"]
print(iam_role_arn)<jupyter_output><empty_output><jupyter_text>Deploy CSI Driver<jupyter_code>!kubectl apply -k "github.com/kubernetes-sigs/aws-fsx-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"<jupyter_output><empty_output><jupyter_text>Patch the driver deployment to add the service account that you just created, replacing the ARN with the correct role ARN.<jupyter_code>!kubectl annotate serviceaccount -n kube-system fsx-csi-controller-sa \
 eks.amazonaws.com/role-arn=$iam_role_arn --overwrite=true<jupyter_output><empty_output><jupyter_text>Check S3 Bucket For FSX<jupyter_code>bucket = "s3://fsx-container-demo"
!aws s3 mb $bucket
!aws s3 ls $bucket
!aws s3 ls $bucket --recursive<jupyter_output><empty_output><jupyter_text>Download Storage Class Manifest<jupyter_code>!curl -o storageclass.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning_s3/specs/storageclass.yaml<jupyter_output><empty_output><jupyter_text>Get VPC ID and Subnet ID<jupyter_code>%%bash

source ~/.bash_profile

#### Get VPC ID
export VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=eksctl-${AWS_CLUSTER_NAME}-cluster/VPC" --query "Vpcs[0].VpcId" --output text)
echo "export VPC_ID=${VPC_ID}" | tee -a ~/.bash_profile

#### Get Subnet ID
export SUBNET_ID=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=${VPC_ID}" --query "Subnets[0].SubnetId" --output text)
echo "export SUBNET_ID=${SUBNET_ID}" | tee -a ~/.bash_profile<jupyter_output><empty_output><jupyter_text>Create Security Group<jupyter_code>%%bash

source ~/.bash_profile

export SEC_GROUP_ID=$(aws ec2 create-security-group --group-name eks-fsx-security-group --vpc-id ${VPC_ID} --description "FSx for Lustre Security Group" --query "GroupId" --output text)
echo "export SEC_GROUP_ID=${SEC_GROUP_ID}" | tee -a ~/.bash_profile<jupyter_output><empty_output><jupyter_text>Add an ingress rule that opens up port 988 from the 192.168.0.0/16 CIDR range<jupyter_code>%%bash

source ~/.bash_profile

aws ec2 authorize-security-group-ingress --group-id ${SEC_GROUP_ID} --protocol tcp --port 988 --cidr 192.168.0.0/16<jupyter_output><empty_output><jupyter_text>Update the environment variables in the `storageclass.yaml` file<jupyter_code>!pygmentize fsx/storageclass.yaml<jupyter_output><empty_output><jupyter_text>Create FSX Storage Class<jupyter_code>#!kubectl delete -f fsx/storageclass.yaml
!kubectl create -f fsx/storageclass.yaml
!kubectl get sc<jupyter_output><empty_output><jupyter_text>Create Claim<jupyter_code>#!curl -o claim.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning_s3/specs/claim.yaml
!pygmentize fsx/claim.yaml
#!kubectl delete -f fsx/claim.yaml
!kubectl apply -f fsx/claim.yaml
!kubectl get pvc fsx-claim
!kubectl describe pvc fsx-claim<jupyter_output><empty_output><jupyter_text>_Wait for status == Bound_  Update FSX to `autoImportPolicy: NEW_CHANGED`<jupyter_code>fsx = boto3.client("fsx")
response = fsx.describe_file_systems()
fsx_id = response["FileSystems"][0]["FileSystemId"]
print(fsx_id)
response = fsx.update_file_system(FileSystemId=fsx_id, LustreConfiguration={"AutoImportPolicy": "NEW_CHANGED"})
print(response)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11843202668890743, 'fraction_numerical': 0.008673894912427023, 'mean_word_length': 6.087470449172577, 'pattern_counts': {'":': 2, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '281701', 'license': 'Apache-2.0', 'n_tokens_mistral': 2190, 'n_tokens_neox': 2106, 'n_words': 440, 'path': '07_train/ml-containers/00_setup_eks/00_04_Setup_FSX.ipynb', 'repo_name': 'MarcusFra/workshop', 'size': '5995'}