Provider Upjet-AWS

repository·main·Indexed 42 days ago

https://github.com/crossplane-contrib/provider-upjet-aws

A Crossplane provider that leverages Upjet code generation to provide managed resources for Amazon AWS. It enables the management of AWS services using Kubernetes-style declarative configuration and supports multiple authentication mechanisms including Secret, IRSA, WebIdentity, and PodIdentity via the aws.upbound.io/v1beta1/ProviderConfig resource.

Tokens
34.7K
Snippets
44
Records
94
Agent score
52%

What's inside Provider Upjet-AWS

  1. Understand the AWS ProviderConfig E2E testing architecture

    main

    The providerconfig-aws-e2e-test package provides a base environment to test various ProviderConfig scenarios for provider-upjet-aws.

    It uses a nested control plane pattern: a local Crossplane control plane manages a remote EKS cluster, which in turn runs its own Crossplane control plane. This remote cluster is bootstrapped with provider-kubernetes and provider-helm from the local control plane.

    Key components provisioned in the test environment include:

    • An AWS EKS cluster.
    • IAM resources for testing IRSA (IAM Roles for Service Accounts) and WebIdentity authentication.
    • Crossplane installed in the EKS cluster.
    • DeploymentRuntimeConfigs to enable IRSA for XP providers.
    • provider-family-aws and example providers (provider-aws-ec2, provider-aws-rds).
    • Various AWS ProviderConfig manifests and example Managed Resources (MRs).
  2. Authentication mechanisms supported by provider-aws

    main

    The provider-aws authenticates to the AWS API using the aws.upbound.io/v1beta1/ProviderConfig resource. You select the authentication mechanism by setting the spec.credentials.source field.

    Supported values for spec.credentials.source:

    • Secret: Uses long-term IAM user credentials stored in a Kubernetes Secret.
    • IRSA: Uses IAM Roles for Service Accounts (requires EKS and IRSA configuration).
    • WebIdentity: Uses an assumed Web identity token.
    • PodIdentity: Uses EKS Pod Identity (requires EKS Pod Identity configuration).

    If no mechanism is specified, the default is Secret.

    Note: For Upbound managed control-planes (MCP), only the Secret mechanism is supported until EKS clusters can be utilized.

  3. Authenticate using EKS Pod Identity

    main

    EKS Pod Identity is an alternative to IRSA that does not require an OIDC provider. It relies on the EKS Pod Identity Agent and the pods.eks.amazonaws.com service principal.

    Setup Steps:

    1. Install the EKS Pod Identity Agent on your cluster.
    2. Create an EKS Pod Identity association between your ServiceAccount and namespace and the target IAM role.
    3. Ensure the ServiceAccount and namespace used by provider-aws match the association.

    Troubleshooting:

    • Verify the namespace and ServiceAccount match the association.
    • Confirm the Pod Identity Agent is functional.
    • Review the IAM role's trust policy for Pod Identity.
    # 1. Configure ServiceAccount via DeploymentRuntimeConfig
    apiVersion: pkg.crossplane.io/v1beta1
    kind: DeploymentRuntimeConfig
    metadata:
        name: podidentity-drc
    spec:
        serviceAccountTemplate:
            metadata:
                name: provider-aws
        deploymentTemplate: {}
    ---
    apiVersion: pkg.crossplane.io/v1
    kind: Provider
    metadata:
      name: upbound-provider-aws-ec2
    spec:
      package: xpkg.upbound.io/upbound/provider-aws-ec2:v1.4.0
      runtimeConfigRef:
        name: podidentity-drc
    ---
    # 2. Configure ProviderConfig
    apiVersion: aws.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
        name: podidentity-example
    spec:
        credentials:
            source: PodIdentity
  4. Authenticate using AWS access keys

    main

    To authenticate the AWS provider using access keys, you must store your credentials in a Kubernetes secret and reference that secret in a ProviderConfig object.

    1. Prepare the credentials file

    Create a text file (e.g., aws-credentials.txt) containing your AWS credentials in INI format:

    [default]
    aws_access_key_id = <aws_access_key>
    aws_secret_access_key = <aws_secret_key>

    2. Create a Kubernetes secret

    Generate a secret from this file using kubectl:

    kubectl create secret generic <secret-name> --from-file=key-file=<aws_credentials_file.txt>

    3. Create a ProviderConfig

    Apply a ProviderConfig that points to the secret. The spec.secretRef must include the namespace, the name of the secret, and the key (which corresponds to the Data field name used when creating the secret, e.g., key-file).

    apiVersion: aws.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
        name: default
    spec:
      credentials:
        source: Secret
        secretRef:
          namespace: default
          name: aws-secret
          key: key-file
  5. Update IAM role trust policy for IRSA

    main

    When using IRSA, the IAM role created (e.g., via eksctl) must have its Trust relationship updated to allow the AWS provider to assume the role.

    1. Identify the OIDC issuer: Use aws eks describe-cluster --name <cluster-name> --query "cluster.identity.oidc.issuer" --output text and strip the https:// prefix.
    2. Construct the Condition: Use StringLike instead of StringEquals. The condition key should follow the pattern: "<oidc-issuer>:sub": "system:serviceaccount:<namespace>:provider-aws-*".
    3. Apply the policy: Use aws iam update-assume-role-policy with a JSON file containing the new policy.
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Federated": "arn:aws:iam::000000000000:oidc-provider/oidc.eks.us-east-2.amazonaws.com/id/266A01FA1DBF8083FA1C23EB7D4736E4"
                },
                "Action": "sts:AssumeRoleWithWebIdentity",
                "Condition": {
                    "StringLike": {
                        "oidc.eks.us-east-2.amazonaws.com/id/266A01FA1DBF8083FA1C23EB7D4736E4:sub": "system:serviceaccount:upbound-system:provider-aws-*"
                    }
                }
            }
        ]
    }
  6. Authenticate using Web Identity

    main

    Web Identity authentication allows you to specify a Web Identity token in the ProviderConfig. This is preferred over using environment variables (AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN), which are now deprecated.

    You can configure the token source in spec.credentials.webIdentity.tokenConfig using either a Secret or a Filesystem path.

    Note: If using Filesystem, the token must be mounted into the provider pod (e.g., via DeploymentRuntimeConfig).

    # Example: Using a Kubernetes Secret for the token
    apiVersion: aws.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
      name: webidentity-example
    spec:
      credentials:
        source: WebIdentity
        webIdentity:
          roleARN: arn:aws:iam::123456789012:role/providerexamplerole
          tokenConfig:
            source: Secret
            secretRef:
              key: token
              name: example-web-identity-token-secret
              namespace: upbound-system
    ---
    # Example: Using a Filesystem path for the token
    apiVersion: aws.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
      name: webidentity-example-fs
    spec:
      credentials:
        source: WebIdentity
        webIdentity:
          roleARN: arn:aws:iam::123456789012:role/providerexamplerole
          tokenConfig:
            source: Filesystem
            fs:
              path: /path/to/token/file
  7. Build and publish the provider locally

    main

    To build the provider locally and prepare it for a local Kubernetes cluster, use the make build.all command. You must specify the DOCKERHUB_ORG, the SUBPACKAGES you are working on (e.g., config and ec2), and set BRANCH_NAME to main to facilitate image publishing to your Docker Hub account.

    Example for building the config and ec2 sub-packages:

    DOCKERHUB_ORG=<your-docker-name>
    BUILD_ARGS="--load" XPKG_REG_ORGS_NO_PROMOTE="" XPKG_REG_ORGS="index.docker.io/$DOCKERHUB_ORG" make build.all publish BRANCH_NAME=main SUBPACKAGES="config ec2"
  8. Authenticate with long-term IAM user credentials

    main

    This method uses a Kubernetes Secret containing long-term IAM user credentials. It is considered less secure than other methods.

    The Secret must contain a credentials key with a base64-encoded file formatted as an AWS shared config file with a [default] profile:

    [default]
    aws_access_key_id=<AWS_ACCESS_KEY_ID>
    aws_secret_access_key=<AWS_SECRET_ACCESS_KEY>

    Then, configure the ProviderConfig to reference this secret.

    apiVersion: v1
    kind: Secret
    metadata:
      name: example-aws-creds
      namespace: upbound-system
    type: Opaque
    data:
      credentials: <base64-encoded credentials file>
    ---
    apiVersion: aws.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
      name: default
    spec:
      credentials:
        source: Secret
        secretRef:
          name: example-aws-creds
          namespace: upbound-system
          key: credentials
  9. Authenticate using IAM Roles for Service Accounts (IRSA)

    main

    For clusters running in Amazon EKS, you can use IAM Roles for Service Accounts (IRSA) to authenticate the AWS provider. This method avoids managing long-lived access keys.

    Prerequisites

    1. Enable IAM OIDC provider: The EKS cluster must have an IAM OIDC provider enabled.
    2. Create an IAM Policy: Define the permissions the provider needs.
    3. Create an IAM Role: An IAM role must be created and associated with a Kubernetes service account.
    4. Update Role Trust Policy: The role's trust relationship must be updated to allow the provider to assume the role using StringLike conditions.
    5. Create a DeploymentRuntimeConfig: This associates the IAM role ARN with the provider's deployment.
    6. Configure the Provider: The Provider must reference the DeploymentRuntimeConfig.
    7. Configure ProviderConfig: The ProviderConfig must be set to use IRSA credentials.
  10. Configure AWS credentials in Kubernetes

    main

    To manage AWS resources, you must provide credentials via a Kubernetes secret in the upbound-system namespace.

    1. Generate a credentials file (e.g., aws-credentials.txt) with the following format:
    [default]
    aws_access_key_id = <aws_access_key>
    aws_secret_access_key = <aws_secret_key>
    1. Create the Kubernetes secret:
    kubectl create secret \
      generic aws-secret \
      -n upbound-system \
      --from-file=creds=./aws-credentials.txt