> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Emr at rest in transit encryption remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are step‑by‑step console instructions to enable **at‑rest** and **in‑transit** encryption for **Amazon Redshift**.

        ***

        ## 1. At‑Rest Encryption (Redshift)

        ### A. Check whether your existing cluster is encrypted

        1. Sign in to the **AWS Management Console**.
        2. Go to **Amazon Redshift** console.
        3. In the left pane, choose **Clusters**.
        4. Click your **cluster identifier**.
        5. On the **Configuration** tab, look for:
           * **Encryption**: Enabled / Disabled
           * **KMS key**: Which KMS key is used, if enabled.

        If **Encryption = Enabled**, at‑rest encryption is already configured.

        > Note: Redshift cluster encryption **cannot be turned on or off for an existing cluster**. You must create a new encrypted cluster and move data.

        ***

        ### B. Create or choose a KMS Customer Managed Key (optional but recommended)

        If you don’t want to use the default AWS managed key:

        1. Open the **AWS KMS** console.
        2. Select **Customer managed keys** → **Create key**.
        3. Choose **Symmetric** → **Next**.
        4. Give it an alias (e.g., `alias/redshift-encryption-key`).
        5. Configure **key administrators** and **key usage permissions** (grant Redshift account roles or IAM roles that will manage the cluster).
        6. Finish key creation.

        ***

        ### C. Create a new encrypted Redshift cluster

        1. In the **Redshift console**, go to **Clusters** → **Create cluster**.
        2. Under **Cluster configuration**, set:
           * **Cluster identifier**, **Node type**, number of nodes as needed.
        3. Under **Database configurations**, set admin username/password.
        4. Under **Security and encryption** (or similar section):
           * Turn **Encryption**: **On**.
           * **KMS key**: Select either:
             * **Default AWS Key for Redshift**, or
             * The customer managed key you created (e.g., `alias/redshift-encryption-key`).
        5. Configure networking/security groups as needed.
        6. Choose **Create cluster**.

        This new cluster will now have **encryption at rest enabled**.

        ***

        ### D. Move data from unencrypted to encrypted cluster

        1. Option 1 – **Snapshot and restore** (if original is encrypted with a different key or you’re cloning an already‑encrypted one):
           * For an unencrypted cluster you can’t create an encrypted snapshot directly; instead:
             * Create a new **encrypted cluster** (done above),
             * Use **UNLOAD** / **COPY** commands to migrate data.

        2. Option 2 – **UNLOAD / COPY**:
           * From the source (unencrypted) cluster:
             * Use `UNLOAD` to export data to **S3** (optionally encrypt S3 objects with SSE‑S3 or SSE‑KMS).
           * From the target (encrypted) cluster:
             * Use `COPY` to load data from S3 into the new cluster.

        3. After validation, point applications to the new encrypted cluster and decommission the old one.

        ***

        ## 2. In‑Transit Encryption (SSL/TLS) for Redshift

        Redshift supports SSL/TLS for connections. You must:

        * Ensure the cluster has **SSL enabled** (it is by default),
        * Optionally enforce SSL in a parameter group,
        * Update clients to use SSL.

        ***

        ### A. Verify or configure SSL requirement via parameter group

        1. Go to the **Redshift** console → **Parameter groups**.
        2. Find the parameter group associated with your cluster:
           * In **Clusters** → select cluster → **Properties** → note the **Parameter group**.
        3. If using the **default** parameter group:
           * You cannot modify it. Create a **new parameter group**:
             1. **Parameter groups** → **Create parameter group**.
             2. Choose:
                * **Parameter group family** matching your engine version.
                * **Group name** and **Description**.
             3. Click **Create**.
        4. Select your (new) parameter group → **Edit parameters**.
        5. Find parameter: `require_ssl`.
           * Set **Value** to `true`.
        6. Save changes.

        ***

        ### B. Attach the parameter group to the cluster

        1. In the **Redshift console**, go to **Clusters**.
        2. Select your cluster → **Actions** → **Modify cluster**.
        3. Under **Database configurations** (or **Cluster properties**):
           * Set **Parameter group** to the new parameter group where `require_ssl = true`.
        4. Save/Apply changes and **reboot** the cluster if prompted:
           * Cluster → **Actions** → **Reboot** (if not done automatically).

        Once applied, the cluster will **reject non‑SSL connections**.

        ***

        ### C. Ensure clients connect using SSL

        For each application / client:

        1. Get cluster endpoint:
           * Redshift console → **Clusters** → select cluster → **General information** → **Endpoint**.
        2. Use **SSL-enabled connection strings**.

        Examples:

        * **psql**:
          ```bash theme={null}
          psql "host=<cluster-endpoint> port=5439 dbname=<db> user=<user> sslmode=require"
          ```

        * **JDBC URL**:
          ```text theme={null}
          jdbc:redshift://<cluster-endpoint>:5439/<db>?ssl=true&sslfactory=com.amazon.redshift.ssl.NonValidatingFactory
          ```

        * **ODBC**:
          * In DSN configuration, enable **SSL** or **Require SSL**.

        3. If you need certificate validation, download Redshift’s public certificate from AWS docs and configure client trust stores accordingly (optional but recommended).

        ***

        ## 3. Validate the Remediation

        * **At rest**:
          * Redshift console → **Clusters** → select cluster → **Configuration**:
            * Confirm **Encryption: Enabled** and correct **KMS key**.
        * **In transit**:
          * Confirm applications can only connect when SSL is enabled.
          * Try a test connection without SSL and verify it fails.

        This completes in‑transit and at‑rest encryption remediation for Amazon Redshift via the AWS console.
      </Accordion>

      <Accordion title="Using CLI">
        For Amazon Redshift, “in‑transit” = SSL, and “at‑rest” = KMS encryption on the cluster.\
        At‑rest encryption cannot be turned on for an existing unencrypted cluster; you must migrate to a new encrypted cluster.

        Below are step‑by‑step AWS CLI instructions.

        ***

        ## 1. At‑Rest Encryption (Redshift)

        ### 1.1. Create (or identify) a KMS key

        ```bash theme={null}
        aws kms create-key --description "Redshift encryption key"
        ```

        Output will include `"KeyId": "arn:aws:kms:region:account-id:key/xxxxxxxx"` – save this ARN.

        Optionally add an alias:

        ```bash theme={null}
        aws kms create-alias \
          --alias-name alias/redshift-kms \
          --target-key-id <kms-key-id-or-arn>
        ```

        You can then use `alias/redshift-kms` instead of the full ARN.

        ***

        ### 1.2. Snapshot your existing unencrypted cluster

        Replace `my-redshift-cluster` and `my-redshift-snapshot`:

        ```bash theme={null}
        aws redshift create-cluster-snapshot \
          --cluster-identifier my-redshift-cluster \
          --snapshot-identifier my-redshift-snapshot
        ```

        Wait until the snapshot is `available`:

        ```bash theme={null}
        aws redshift describe-cluster-snapshots \
          --snapshot-identifier my-redshift-snapshot \
          --query "Snapshots[0].Status"
        ```

        ***

        ### 1.3. Restore a new encrypted cluster from the snapshot

        ```bash theme={null}
        aws redshift restore-from-cluster-snapshot \
          --cluster-identifier my-redshift-cluster-encrypted \
          --snapshot-identifier my-redshift-snapshot \
          --encrypted \
          --kms-key-id alias/redshift-kms
        ```

        You can also specify node type, security groups, etc., if you want to override snapshot defaults (optional):

        ```bash theme={null}
        aws redshift restore-from-cluster-snapshot \
          --cluster-identifier my-redshift-cluster-encrypted \
          --snapshot-identifier my-redshift-snapshot \
          --encrypted \
          --kms-key-id alias/redshift-kms \
          --node-type ra3.xlplus \
          --cluster-subnet-group-name my-subnet-group \
          --vpc-security-group-ids sg-xxxxxxxx \
          --publicly-accessible false
        ```

        Wait until the new cluster is `available`:

        ```bash theme={null}
        aws redshift describe-clusters \
          --cluster-identifier my-redshift-cluster-encrypted \
          --query "Clusters[0].ClusterStatus"
        ```

        ***

        ### 1.4. Cut over and clean up

        1. Update applications to point to the new cluster’s endpoint (from `describe-clusters`).
        2. When fully migrated, delete the old unencrypted cluster:

        ```bash theme={null}
        aws redshift delete-cluster \
          --cluster-identifier my-redshift-cluster \
          --skip-final-cluster-snapshot
        ```

        (Or omit `--skip-final-cluster-snapshot` and specify `--final-cluster-snapshot-identifier` if you want a final backup.)

        ***

        ## 2. In‑Transit Encryption (SSL) for Redshift

        To enforce SSL, configure a parameter group and apply it to the cluster.

        ### 2.1. Create a parameter group (if you don’t already have a custom one)

        ```bash theme={null}
        aws redshift create-cluster-parameter-group \
          --parameter-group-name my-redshift-ssl-pg \
          --parameter-group-family redshift-1.0 \
          --description "Require SSL for Redshift"
        ```

        (Use `redshift-1.0` or the family appropriate to your engine version.)

        ***

        ### 2.2. Set `require_ssl` to `true`

        ```bash theme={null}
        aws redshift modify-cluster-parameter-group \
          --parameter-group-name my-redshift-ssl-pg \
          --parameters "ParameterName=require_ssl,ParameterValue=true,Description=RequireSSL,ApplyType=static"
        ```

        You can verify:

        ```bash theme={null}
        aws redshift describe-cluster-parameters \
          --parameter-group-name my-redshift-ssl-pg \
          --query "Parameters[?ParameterName=='require_ssl']"
        ```

        ***

        ### 2.3. Attach the parameter group to your (encrypted) cluster

        ```bash theme={null}
        aws redshift modify-cluster \
          --cluster-identifier my-redshift-cluster-encrypted \
          --cluster-parameter-group-name my-redshift-ssl-pg
        ```

        You must reboot for static parameters to take effect:

        ```bash theme={null}
        aws redshift reboot-cluster \
          --cluster-identifier my-redshift-cluster-encrypted
        ```

        ***

        ### 2.4. Ensure clients actually use SSL

        Redshift will now require SSL, but your clients must be configured correctly:

        * JDBC: `ssl=true` or `sslmode=require` in the connection string.
        * ODBC: enable SSL / require SSL in DSN settings.
        * psql: `sslmode=require` (or `verify-ca`/`verify-full` with appropriate CA).

        No extra CLI steps are needed here; this is client configuration.

        ***

        ## 3. Quick Verification

        **At‑rest encryption:**

        ```bash theme={null}
        aws redshift describe-clusters \
          --cluster-identifier my-redshift-cluster-encrypted \
          --query "Clusters[0].[Encrypted,KmsKeyId]"
        ```

        Should return `true` and the KMS key.

        **In‑transit (SSL) enforcement:**

        ```bash theme={null}
        aws redshift describe-clusters \
          --cluster-identifier my-redshift-cluster-encrypted \
          --query "Clusters[0].ClusterParameterGroups"
        ```

        Make sure `my-redshift-ssl-pg` is attached and `ParameterApplyStatus` is `in-sync`. Then test connections; non‑SSL connections should fail.

        If you share your current cluster identifier and whether it’s already encrypted, I can tailor exact CLI commands for your environment.
      </Accordion>

      <Accordion title="Using Python">
        For Amazon Redshift, “in-transit” = SSL/TLS for client connections; “at-rest” = KMS-encrypted data on disk (cluster + snapshots).\
        Below is how to remediate both using Python (boto3).

        ***

        ## Prereqs

        ```bash theme={null}
        pip install boto3
        ```

        ```python theme={null}
        import boto3

        redshift = boto3.client("redshift", region_name="us-east-1")  # adjust region
        ```

        Replace placeholders like `<CLUSTER_IDENTIFIER>`, `<KMS_KEY_ARN>` as needed.

        ***

        ## 1. At-Rest Encryption

        ### A. New cluster (easiest)

        You **cannot enable encryption on an existing unencrypted cluster**; you must create a new encrypted one and migrate.

        1. Create an encrypted snapshot of the old cluster (unencrypted snapshot → restore as encrypted).

        ```python theme={null}
        # 1. Take snapshot of existing (unencrypted) cluster
        snapshot_id = "old-cluster-snapshot"
        redshift.create_cluster_snapshot(
            SnapshotIdentifier=snapshot_id,
            ClusterIdentifier="<OLD_CLUSTER_IDENTIFIER>"
        )
        ```

        2. Wait for snapshot to be available (poll or use waiter):

        ```python theme={null}
        waiter = redshift.get_waiter('snapshot_available')
        waiter.wait(SnapshotIdentifier=snapshot_id)
        ```

        3. Restore snapshot to a **new encrypted cluster**:

        ```python theme={null}
        redshift.restore_from_cluster_snapshot(
            ClusterIdentifier="<NEW_ENCRYPTED_CLUSTER>",
            SnapshotIdentifier=snapshot_id,
            Encrypted=True,
            KmsKeyId="<KMS_KEY_ARN>"  # or omit to use AWS managed key
        )
        ```

        4. Wait for new cluster to be available:

        ```python theme={null}
        waiter = redshift.get_waiter('cluster_available')
        waiter.wait(ClusterIdentifier="<NEW_ENCRYPTED_CLUSTER>")
        ```

        5. Update clients / apps / connection strings to point to the new cluster’s endpoint, test, then delete the old cluster:

        ```python theme={null}
        redshift.delete_cluster(
            ClusterIdentifier="<OLD_CLUSTER_IDENTIFIER>",
            SkipFinalClusterSnapshot=True  # or create final snapshot if needed
        )
        ```

        Now your data at rest (cluster & snapshots) is encrypted.

        ***

        ### B. Ensuring snapshots are encrypted

        For an **already encrypted** cluster, snapshots are encrypted automatically with the same KMS key.\
        To ensure cross-region snapshot copy is encrypted:

        ```python theme={null}
        redshift.enable_snapshot_copy(
            ClusterIdentifier="<ENCRYPTED_CLUSTER>",
            DestinationRegion="us-west-2",
            RetentionPeriod=7,
            SnapshotCopyGrantName="<SNAPSHOT_COPY_GRANT_NAME>",
            KmsKeyId="<DEST_REGION_KMS_KEY_ARN>"
        )
        ```

        ***

        ## 2. In-Transit Encryption (SSL/TLS)

        You enable and enforce SSL via a parameter group (`require_ssl`).

        ### A. Create / update a parameter group with `require_ssl=1`

        1. Create a new parameter group (if you don’t want to modify an existing one):

        ```python theme={null}
        param_group_name = "redshift-ssl-required"

        redshift.create_cluster_parameter_group(
            ParameterGroupName=param_group_name,
            ParameterGroupFamily="redshift-1.0",  # check your engine family
            Description="Require SSL for all connections"
        )
        ```

        2. Set `require_ssl = true` (1):

        ```python theme={null}
        redshift.modify_cluster_parameter_group(
            ParameterGroupName=param_group_name,
            Parameters=[
                {
                    "ParameterName": "require_ssl",
                    "ParameterValue": "true",  # or "1"
                    "Description": "Force SSL for all DB connections",
                    "Source": "user",
                    "DataType": "boolean",
                    "AllowedValues": "true,false",
                    "IsModifiable": True,
                    "ApplyType": "static"
                }
            ]
        )
        ```

        > `require_ssl` is a static parameter → cluster must be rebooted after the parameter group is associated.

        ### B. Attach the parameter group to your cluster

        ```python theme={null}
        redshift.modify_cluster(
            ClusterIdentifier="<CLUSTER_IDENTIFIER>",
            ClusterParameterGroupName=param_group_name
        )
        ```

        Then reboot (or wait for Redshift to apply & manually reboot):

        ```python theme={null}
        redshift.reboot_cluster(ClusterIdentifier="<CLUSTER_IDENTIFIER>")
        ```

        ***

        ## 3. Enforce SSL From Clients

        After `require_ssl` is on, non-SSL connections will fail.\
        Make sure your Python clients use SSL, for example with `psycopg2`:

        ```python theme={null}
        import psycopg2

        conn = psycopg2.connect(
            dbname="<DB_NAME>",
            user="<USER>",
            password="<PASSWORD>",
            host="<REDSHIFT_ENDPOINT>",
            port=5439,
            sslmode="require"  # or "verify-full" with CA bundle
        )
        ```

        ***

        ## Summary

        1. **At rest** (Redshift):
           * Existing unencrypted: snapshot → restore encrypted cluster (with `Encrypted=True`, `KmsKeyId=...`) → switch traffic → delete old cluster.
           * New clusters: always create with `Encrypted=True`.
        2. **In transit**:
           * Create/modify parameter group: set `require_ssl=true`.
           * Attach parameter group, reboot cluster.
           * Ensure all clients connect with `sslmode=require` (or stronger).
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # At-rest encryption for an existing Redshift cluster
        # NOTE: Changing `encrypted` from false→true forces replacement of the cluster
        # (full recreate, data loss unless you restore from snapshot).

        resource "aws_redshift_cluster" "this" {
          cluster_identifier = "REDSHIFT_CLUSTER_IDENTIFIER" # e.g., "analytics-prod"
          node_type          = "dc2.large"
          master_username    = "MASTER_USERNAME"
          master_password    = "MASTER_PASSWORD"

          # Enable encryption at rest
          encrypted = true

          # Optionally use a customer-managed KMS key (recommended)
          # Omit this line to use the default Redshift KMS key
          kms_key_id = "KMS_KEY_ARN_OR_ID"

          # Attach the parameter group that enforces SSL (see below)
          cluster_parameter_group_name = aws_redshift_parameter_group.ssl_enforced.name

          # ...other required arguments (subnets, security groups, etc) ...
        }

        # In-transit encryption: enforce SSL for all connections
        resource "aws_redshift_parameter_group" "ssl_enforced" {
          name        = "REDSHIFT_SSL_REQUIRED_PARAMETER_GROUP_NAME"
          family      = "redshift-1.0"
          description = "Require SSL for all client connections"

          parameter {
            name  = "require_ssl"
            value = "true"
          }
        }
        ```

        To verify, `terraform plan` should show `encrypted = true`, the desired `kms_key_id` on `aws_redshift_cluster.this`, and `parameter.require_ssl` changing/created as `value = "true"` on `aws_redshift_parameter_group.ssl_enforced`, with a note that the cluster will be replaced if it was previously unencrypted.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
