Integrating Istio with AWS Private Certificate Authority (PCA)
Introduction
This guide offers detailed, step-by-step instructions to help you set up a custom Certificate Authority (CA) for Istio, leveraging AWS PCA's managed infrastructure and cert-manager's automation capabilities.
Architecture Overview
The integration involves the following components:
- AWS Private CA: A managed service that provides a secure CA hierarchy.
- cert-manager: Automates the issuance and renewal of certificates in Kubernetes.
- AWS PCA Issuer Plugin: Enables cert-manager to interact with AWS PCA.
- Istio: Configured to use the custom CA for issuing mTLS certificates within the service mesh.
Prerequisites
Before you begin, ensure you have the following:
- AWS Account: With permissions to manage AWS PCA and IAM roles.
- AWS PCA: Access to create and manage CAs.
- Tetrate Istio Subscription (TIS): Deployed in your Kubernetes cluster.
- Kubernetes Cluster: With cluster admin access.
- kubectl: Configured to interact with your cluster.
- Helm: Installed on your local machine.
- cert-manager: Version 1.0.0 or later.
- AWS CLI: Configured with appropriate permissions.
- IAM Roles and Policies: Ability to create IAM roles and policies.
- OpenSSL: For certificate inspection (optional).
Steps
Step 1: Install cert-manager
cert-manager simplifies certificate management in Kubernetes clusters.
- 
Add the Jetstack Helm Repository: helm repo add jetstack https://charts.jetstack.io --force-update
- 
Install cert-manager: helm install \
 cert-manager jetstack/cert-manager \
 --namespace cert-manager \
 --create-namespace \
 --version v1.15.3 \
 --set crds.enabled=true
- 
Verify Installation: kubectl -n cert-manager get podsEnsure all cert-manager pods are in the Runningstate.
Step 2: Set Up AWS Private Certificate Authority
Create a CA hierarchy in AWS PCA to issue certificates for Istio.
- 
Create a Root CA: - Navigate to the AWS PCA console.
- Choose Create a private CA and select Root CA.
- Provide the required information (e.g., Organization, Country).
- Activate the CA by installing the self-signed certificate.
 
- 
Create a Subordinate CA: - Choose Create a private CA and select Subordinate CA.
- Provide the necessary details.
- Install a certificate from the parent CA.
- Note that when installing the subordinate certificate, do not specify the path length parameter as 0, otherwise a CA cannot be created for Istio.
 
- 
Note the CA ARN: Record the Amazon Resource Name (ARN) of the subordinate CA; it will be used later. export ISTIO_CA_ARN="arn:aws:acm-pca:region:account-id:certificate-authority/CA_ID"Alternatively, if you have an existing CA hierarchy, you can use its ARN. 
Step 3: Create IAM Policy and Role
Create an IAM policy and role to allow cert-manager to interact with AWS PCA.
- 
Create an IAM Policy: cat <<EOF > AWSPCAIssuerPolicy.json
 {
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "acm-pca:DescribeCertificateAuthority",
 "acm-pca:GetCertificate",
 "acm-pca:IssueCertificate"
 ],
 "Resource": "${ISTIO_CA_ARN}"
 }
 ]
 }
 EOF
 aws iam create-policy \
 --policy-name AWSPCAIssuerPolicy \
 --policy-document file://AWSPCAIssuerPolicy.json
- 
Create an IAM Role with OIDC Provider: - 
Enable OIDC Provider for your EKS cluster (if not already enabled): eksctl utils associate-iam-oidc-provider \
 --cluster your-cluster-name \
 --approve
- 
Create the IAM Role: eksctl create iamserviceaccount \
 --name aws-pca-issuer \
 --namespace cert-manager \
 --cluster your-cluster-name \
 --attach-policy-arn arn:aws:iam::your-account-id:policy/AWSPCAIssuerPolicy \
 --approve \
 --override-existing-serviceaccountsThis command creates a service account aws-pca-issuerin thecert-managernamespace with the necessary permissions.
 
- 
Step 4: Install AWS PCA Issuer Plugin
Install the AWS PCA Issuer plugin to allow cert-manager to request certificates from AWS PCA.
- 
Add the AWS PCA Issuer Helm Repository: helm repo add awspca https://cert-manager.github.io/aws-privateca-issuer
 helm repo update
- 
Install the AWS PCA Issuer: helm install aws-pca-issuer awspca/aws-privateca-issuer \
 --namespace cert-manager \
 --set serviceAccount.create=false \
 --set serviceAccount.name=aws-pca-issuer \
 --wait
- 
Verify Installation: kubectl -n cert-manager get podsEnsure the aws-pca-issuerpod is running.
Step 5: Configure the AWS PCA Issuer
Create an AWSPCAIssuer resource to define how cert-manager interacts with AWS PCA.
- 
Create the Issuer Resource: kubectl create namespace istio-system
 cat <<EOF | kubectl apply -f -
 apiVersion: awspca.cert-manager.io/v1beta1
 kind: AWSPCAIssuer
 metadata:
 name: aws-pca-issuer-istio
 namespace: istio-system
 spec:
 arn: ${ISTIO_CA_ARN}
 region: your-aws-region
 EOFReplace your-aws-regionwith the AWS region where your PCA is located.
- 
Verify the Issuer: kubectl -n istio-system describe awspcaissuer aws-pca-issuer-istioEnsure the issuer's status is Ready.
Step 6: Create the Istio CA Certificate
Use cert-manager to generate a CA certificate for Istio.
- 
Create the Certificate Resource: cat <<EOF | kubectl apply -f -
 apiVersion: cert-manager.io/v1
 kind: Certificate
 metadata:
 name: istio-ca
 namespace: istio-system
 spec:
 isCA: true
 commonName: istio-ca
 duration: 2160h # 90 days
 renewBefore: 360h # 15 days before expiration
 privateKey:
 algorithm: RSA
 size: 2048
 secretName: cacerts
 issuerRef:
 name: aws-pca-issuer-istio
 kind: AWSPCAIssuer
 group: awspca.cert-manager.io
 EOF
- 
Verify Certificate Creation: kubectl -n istio-system get certificate istio-ca
 kubectl -n istio-system get secret cacertsEnsure the cacertssecret is created and contains the certificate data.
Step 7: Install Istio
Install Istio by referring to the TIS document.
Step 8: Deploy Sample Applications
Deploy sample workloads to test the mTLS communication with the custom CA.
- 
Deploy the Bookinfo Application: kubectl label namespace default istio-injection=enabled
 kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
- 
Verify Application Pods: kubectl get podsEnsure all application pods are running with sidecar injection. 
Step 9: Verify the Certificate Chain
Confirm that the pods' certificates are issued by AWS PCA.
- 
Inspect the productpage pod’s certificate trust chain: istioctl -n default proxy-config secret deployment/productpage-v1 -o json | jq -r \
 '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | base64 --decode > chain.pem
- 
Split the certificate chain: split -p "-----BEGIN CERTIFICATE-----" chain.pem cert-You will see five certificates named from cert-aatocert-ae. The certificate trust chain is structured ascert-aa -> cert-ab -> cert-ac -> cert-ad, with the last certificatecert-aebeing the root certificate, identical tocert-ad. Check the issuer information in the certificate details to ensure it aligns with your AWS PCA configuration.The following figure shows the certificates trust chain. 
- 
Match Serial Numbers: - 
Inspect the serial number from the certificate: openssl x509 -in cert-ad -noout -serial | cut -d'=' -f2 | tr -d '\n' | xargs -I {} echo "ibase=16; {}" | bc
 openssl x509 -in cert-ac -noout -serial | cut -d'=' -f2 | tr -d '\n' | xargs -I {} echo "ibase=16; {}" | bc
- 
Compare it with the serial number of the certificate in AWS PCA console. 
 
- 
Troubleshooting Tips
- 
Check AWSPCAIssuer Status: kubectl -n istio-system describe awspcaissuer aws-pca-issuer-istio
- 
Inspect CertificateRequest Objects: kubectl -n istio-system get certificaterequests
 kubectl -n istio-system describe certificaterequest istio-ca-xxxxx
- 
Review Logs: - 
cert-manager: kubectl -n cert-manager logs deploy/cert-manager
- 
AWS PCA Issuer: kubectl -n cert-manager logs deploy/aws-pca-issuer-aws-privateca-issuer
 
-