AWS

Prerequisites

To manage any Cloud Account using the instructions below, you need:

  • The humctl CLI installed.

  • These environment variables set:

    export HUMANITEC_ORG=<your-humanitec-org-id>
    export HUMANITEC_TOKEN=<humanitec-access-token>
    

AWS Role Assumption

Credentials: dynamic

Create the Cloud Account

AWS temporary credentials make use of the AssumeRole API operation. You need to first prepare the trust relationship on the AWS side and then create the actual Humanitec Cloud Account.

  1. Create a non-guessable ExternalId that will uniquely identify the Cloud Account in the Humanitec Platform Orchestrator. For a UUID, you can use the uuidgen tool.

    export EXTERNAL_ID=$(uuidgen)
    
  2. Create an IAM role to establish a trust relationship between your trusting account and the public Humanitec AWS user with the ARN “arn:aws:iam::767398028804:user/humanitec”. An additional trust policy expands the role to the ExternalId you created before. The Humanitec Cloud Account will later be configured with both elements so that it can effectively assume this IAM role.

    First prepare the trust policy:

    cat <<EOF > trust-policy.json
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::767398028804:user/humanitec"
          },
          "Action": "sts:AssumeRole",
          "Condition": {
            "StringEquals": {
              "sts:ExternalId": "${EXTERNAL_ID}"
            }
          }
        }
      ]
    }
    EOF
    

    Define the name of the new role according to your own naming schema:

    export ROLE_NAME=humanitec-access-tempcreds
    

    Create the IAM role including the trust policy and capture its ARN:

    export ROLE_ARN=$(aws iam create-role --role-name ${ROLE_NAME} \
      --assume-role-policy-document file://trust-policy.json \
      | jq .Role.Arn | tr -d "\"")
    echo ${ROLE_ARN}
    
  3. Prepare an IAM policy defining the required permissions, e.g. accessing an EKS cluster.

    First prepare the IAM policy. Adjust actions and resources as required:

    cat <<EOF > role-policy.json
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "eks:DescribeNodegroup",
            "eks:ListNodegroups",
            "eks:AccessKubernetesApi",
            "eks:DescribeCluster"
          ],
          "Resource": "arn:aws:eks:us-west-2:111122223333:cluster/my-cluster"
        }
      ]
    }
    EOF
    

    Define the name of the new IAM policy according to your own naming schema:

    export POLICY_NAME=AdministratorAccess_EKS_MyCluster
    

    Create the IAM policy and capture its ARN:

    export POLICY_ARN=$(aws iam create-policy \
      --policy-name ${POLICY_NAME} \
      --policy-document file://role-policy.json \
      | jq .Policy.Arn | tr -d "\"")
    echo ${POLICY_ARN}
    
  4. Attach the IAM policy to the IAM role:

    aws iam attach-role-policy \
      --role-name ${ROLE_NAME} \
      --policy-arn ${POLICY_ARN}
    
  5. Create a Cloud Account in the Platform Orchestrator.

    Define the name and id of the new Cloud Account:

    export CLOUD_ACCOUNT_NAME="My AWS Temp Cred Account"
    export CLOUD_ACCOUNT_ID=my-aws-temp-cred
    

    If you haven’t already done so (see Prerequisites), define these environment variables:

    export HUMANITEC_ORG=<your-humanitec-org-id>
    export HUMANITEC_TOKEN=<humanitec-access-token>
    

    Create the Cloud Account:

    humctl api post /orgs/${HUMANITEC_ORG}/resources/accounts \
    -d '{
      "name": "'"${CLOUD_ACCOUNT_NAME}"'",
      "id": "'"${CLOUD_ACCOUNT_ID}"'",
      "type": "aws-role",
      "credentials": {
        "aws_role": "'"${ROLE_ARN}"'",
        "external_id": "'"${EXTERNAL_ID}"'"
      }
    }
    '
    

    Using the Humanitec Terraform Provider:

    resource "humanitec_resource_account" "aws-role" {
      id   = var.cloud_account_id
      name = var.cloud_account_name
      type = "aws-role"
      credentials = jsonencode({
        aws_role    = var.aws_iam_role_tempcreds_arn
        external_id = var.aws_dynamic_credentials_external_id
      })
    }
    

    Inside the API, Cloud Accounts are called Resource Accounts, both represent the same entity.

  6. Assign the required permissions to the IAM role.

    The Cloud Account is now ready for use by any Drivers supporting the aws-role Account type. See the usage examples below to get started. Remember to assign the required permissions to the IAM Role on the target AWS services depending on the kind of operations it needs to perform.

Example: connect to an EKS cluster

This example Resource Definition is using the k8s-cluster-eks Driver to facilitate deployments to an Amazon EKS cluster. All it takes for this to work is to include a Cloud Account of type aws-role via the driver_account setting. Dynamic credentials will be automatically generated and picked up by the Driver with no further configuration required.


eks-dynamic-credentials.yaml (view on GitHub) :

# Connect to an EKS cluster using dynamic credentials defined via a Cloud Account
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: eks-dynamic-credentials
entity:
  name: eks-dynamic-credentials
  type: k8s-cluster
  # The driver_account references a Cloud Account of type "aws-role"
  # which needs to be configured for your Organization.
  driver_account: aws-temp-creds
  # The driver_type k8s-cluster-eks automatically handles the dynamic credentials
  # injected via the driver_account.
  driver_type: humanitec/k8s-cluster-eks
  driver_inputs:
    values:
      region: eu-central-1
      name: demo-123
      loadbalancer: x111111xxx111111111x1xx1x111111x-x111x1x11xx111x1.elb.eu-central-1.amazonaws.com
      loadbalancer_hosted_zone: ABC0DEF5WYYZ00

Example: provision an S3 bucket

This example Resource Definition uses the Terraform Driver to provision S3 buckets. It includes a Cloud Account of type aws-role via the driver_account setting. Dynamic credentials will be automatically generated and made available for passing into the Terraform code as required.


s3-dynamic-credentials.yaml (view on GitHub) :

# Connect to an EKS cluster using dynamic credentials defined via a Cloud Account
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: s3-dynamic-credentials
entity:
  name: s3-dynamic-credentials
  type: s3
  driver_type: humanitec/terraform
  # The driver_account references a Cloud Account of type "aws-role"
  # which needs to be configured for your Organization.
  driver_account: aws-temp-creds
  driver_inputs:
    values:
      variables:
        REGION: eu-central-1
      # Use the credentials injected via the driver_account
      # to set variables as expected by your Terraform code
      credentials_config:
        variables:
          ACCESS_KEY_ID: AccessKeyId
          ACCESS_KEY_VALUE: SecretAccessKey
          SESSION_TOKEN: SessionToken
      script: |-
        # This provider block is using the Terraform variables
        # set through the credentials_config.
        # Variable declarations omitted for brevity.
        provider "aws" {
          region     = var.REGION
          access_key = var.ACCESS_KEY_ID
          secret_key = var.ACCESS_KEY_VALUE
          token      = var.SESSION_TOKEN
        }

        # ... Terraform code reduced for brevity

        resource "aws_s3_bucket" "bucket" {
          bucket = my-bucket
        }

AWS User with access key & secret

Credentials: static

Create the Cloud Account

  1. Create an IAM user which will be used by the Humanitec Platform Orchestrator.

    Define the name of the new role according to your own naming schema:

    export USER_NAME=humanitec-user
    

    Create a new IAM User:

    aws iam create-user --user-name ${USER_NAME}
    
  2. Prepare an IAM policy defining the required permissions, e.g. accessing an EKS cluster.

    First prepare the IAM policy. Adjust actions and resources as required:

    cat <<EOF > role-policy.json
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "eks:DescribeNodegroup",
            "eks:ListNodegroups",
            "eks:AccessKubernetesApi",
            "eks:DescribeCluster"
          ],
          "Resource": "arn:aws:eks:us-west-2:111122223333:cluster/my-cluster"
        }
      ]
    }
    EOF
    

    Define the name of the new IAM policy according to your own naming schema:

    export POLICY_NAME=AdministratorAccess_EKS_MyCluster
    

    Create the IAM policy and capture its ARN:

    export POLICY_ARN=$(aws iam create-policy \
      --policy-name ${POLICY_NAME} \
      --policy-document file://role-policy.json \
      | jq .Policy.Arn | tr -d "\"")
    echo ${POLICY_ARN}
    
  3. Attach the IAM policy to the IAM role:

    aws iam attach-user-policy \
      --user-name ${USER_NAME} \
      --policy-arn ${POLICY_ARN}
    
  4. Create access keys.

    export KEY_OUTPUT=$(aws iam create-access-key \
      --user-name ${USER_NAME})
    

    Export the values, needed for the Cloud Account:

    export AWS_ACCESS_KEY_ID=$(echo $KEY_OUTPUT | jq -rM .AccessKey.AccessKeyId )
    export AWS_SECRET_ACCESS_KEY=$(echo $KEY_OUTPUT | jq -rM .AccessKey.SecretAccessKey )
    
  5. Create a Cloud Account in the Platform Orchestrator.

    Define the name and id of the new Cloud Account:

    export CLOUD_ACCOUNT_NAME="My AWS User Account"
    export CLOUD_ACCOUNT_ID=my-aws-user-cred
    

    If you haven’t already done so (see Prerequisites), define these environment variables:

    export HUMANITEC_ORG=<your-humanitec-org-id>
    export HUMANITEC_TOKEN=<humanitec-access-token>
    

    Create the Cloud Account:

    humctl api post /orgs/${HUMANITEC_ORG}/resources/accounts \
    -d '{
      "name": "'"${CLOUD_ACCOUNT_NAME}"'",
      "id": "'"${CLOUD_ACCOUNT_ID}"'",
      "type": "aws",
      "credentials": {
        "aws_access_key_id": "'"${AWS_ACCESS_KEY_ID}"'",
        "aws_secret_access_key": "'"${AWS_SECRET_ACCESS_KEY}"'"
      }
    }
    '
    

    Using the Humanitec Terraform Provider:

    resource "humanitec_resource_account" "aws" {
      id   = var.cloud_account_id
      name = var.cloud_account_name
      type = "aws"
      credentials = jsonencode({
        aws_access_key_id     = var.aws_access_key_id
        aws_secret_access_key = var.aws_secret_access_key
      })
    }
    

    Inside the API, Cloud Accounts are called Resource Accounts, both represent the same entity.

  6. Assign the required permissions to the IAM user.

    The Cloud Account is now ready for use by any Drivers supporting the aws Account type. See the usage examples below to get started. Remember to assign the required permissions to the IAM User on the target AWS services depending on the kind of operations it needs to perform.

Example: connect to an EKS cluster

This example Resource Definition is using the k8s-cluster-eks Driver to facilitate deployments to an Amazon EKS cluster. All it takes for this to work is to include a Cloud Account of type aws via the driver_account setting. The Cloud Account credentials will be automatically generated and picked up by the Driver with no further configuration required.


eks-static-credentials-cloudaccount.yaml (view on GitHub) :

# Connect to an EKS cluster using static credentials defined via a Cloud Account
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: eks-static-credentials-cloudaccount
entity:
  name: eks-static-credentials-cloudaccount
  type: k8s-cluster
  # The driver_account references a Cloud Account of type "aws"
  # which needs to be configured for your Organization.
  driver_account: aws-static-creds
  # The driver_type k8s-cluster-eks automatically handles the static credentials
  # injected via the driver_account.
  driver_type: humanitec/k8s-cluster-eks
  driver_inputs:
    values:
      region: eu-central-1
      name: demo-123
      loadbalancer: x111111xxx111111111x1xx1x111111x-x111x1x11xx111x1.elb.eu-central-1.amazonaws.com
      loadbalancer_hosted_zone: ABC0DEF5WYYZ00
Top