From a08a897a2615d0c7e984ebee8842d795cf6d84b9 Mon Sep 17 00:00:00 2001
From: Emmanuel CAMPER <emmanuel.camper@orange.com>
Date: Fri, 21 Feb 2025 11:46:10 +0100
Subject: [PATCH] feat(AWS): add AWS authent with STS

---
 README.md                       | 43 +++++++++++++++++
 kicker.json                     | 44 ++++++++++++++++++
 templates/gitlab-ci-k8s-aws.yml | 82 +++++++++++++++++++++++++++++++++
 3 files changed, 169 insertions(+)
 create mode 100644 templates/gitlab-ci-k8s-aws.yml

diff --git a/README.md b/README.md
index 757b93f..f2e88cd 100644
--- a/README.md
+++ b/README.md
@@ -600,3 +600,46 @@ include:
       gcp-prod-oidc-provider: "projects/<gcp_prod_proj_id>/locations/global/workloadIdentityPools/<pool_id>/providers/<provider_id>"
       gcp-prod-oidc-account: "<name>@$<gcp_prod_proj_id>.iam.gserviceaccount.com"
 ```
+
+### Amazon Web service variant
+
+This variant use the OIDC and [AWS STS](https://docs.aws.amazon.com/fr_fr/STS/latest/APIReference/welcome.html) in AWS to get credential
+
+#### Prerequesite
+
+- [Create an OpenID Connect (OIDC) identity provider in IAM
+  ](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)
+- [Configure a web identity role](https://docs.gitlab.com/ee/ci/cloud_services/aws/#configure-a-role-and-trust)
+
+#### Configuration
+
+The  image from alpine `k8s` is required for the use of aws-iam-authenticator.
+  
+The variant requires the additional configuration parameters :
+
+| Input / Variable                                          | Description                                                                                                                                                                            | Default value    |
+|-----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|
+| `aws-oidc-aud` / `AWS_OIDC_AUD`                           | The `aud` claim for the JWT token                                                                                                                                                      | `$CI_SERVER_URL` |
+| `aws-oidc-role-arn` / `AWS_OIDC_ROLE_ARN`                 | Default IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/)                                                  | _none_           |
+| `aws-review-oidc-role-arn` / `AWS_REVIEW_OIDC_ROLE_ARN`   | IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `review` env _(only define to override default)_      | _none_           |
+| `aws-integ-oidc-role-arn` / `AWS_INTEG_OIDC_ROLE_ARN`     | IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `integration` env _(only define to override default)_ | _none_           |
+| `aws-staging-oidc-role-arn` / `AWS_STAGING_OIDC_ROLE_ARN` | IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `staging` env _(only define to override default)_     | _none_           |
+| `aws-prod-oidc-role-arn` / `AWS_PROD_OIDC_ROLE_ARN`       | IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `production` env _(only define to override default)_  | _none_           |
+| `kubectl-image` / `K8S_KUBECTL_IMAGE`                     | The Docker image used to run Kubernetes `kubectl` commands on [AWS]                                                                                                                    | `docker.io/alpine/k8s:1.32.1` |
+
+#### Example
+
+With a common default `AWS_OIDC_ROLE_ARN`  configuration for non-prod environments, and a specific one for production:
+
+```yaml
+include:
+  # main template
+  - component: $CI_SERVER_FQDN/to-be-continuous/kubernetes/gitlab-ci-k8s@7.1.1
+  # AWS variant
+  - component: $CI_SERVER_FQDN/to-be-continuous/kubernetes/gitlab-ci-k8s-aws@7.1.1
+    inputs:
+      # common OIDC config for non-prod envs
+      aws-oidc-role-arn: "arn:aws:iam::<project_id>:role/<role_name>"
+      # specific OIDC config for prod
+      aws-prod-oidc-role-arn: "arn:aws:iam::<project_id>:role/<role_name>"
+```
\ No newline at end of file
diff --git a/kicker.json b/kicker.json
index cf95473..7cfccee 100644
--- a/kicker.json
+++ b/kicker.json
@@ -376,6 +376,50 @@
           "default": "gcr.io/google.com/cloudsdktool/cloud-sdk:latest"
         }
       ]
+    },
+    {
+      "id": "aws-auth-provider",
+      "name": "Amazon Web service",
+      "description": "This variant uses [OpenID Connect in AWS] to retrieve temporary credentials.",
+      "template_path": "templates/gitlab-ci-k8s-aws.yml",
+      "variables": [
+        {
+          "name": "AWS_OIDC_AUD",
+          "description": "The `aud` claim for the JWT token _(only required for [OIDC authentication](https://docs.gitlab.com/ee/ci/cloud_services/aws/))_",
+          "default": "$CI_SERVER_URL",
+          "advanced": true
+        },
+        {
+          "name": "AWS_OIDC_ROLE_ARN",
+          "description": "The default role ARN configured",
+          "advanced": true
+        },
+        {
+          "name": "AWS_REVIEW_OIDC_ROLE_ARN",
+          "description": "The role ARN configured for `review` environment",
+          "advanced": true
+        },
+        {
+          "name": "AWS_INTEG_OIDC_ROLE_ARN",
+          "description": "The role ARN configured for `integration` environment",
+          "advanced": true
+        },
+        {
+          "name": "AWS_STAGING_OIDC_ROLE_ARN",
+          "description": "The role ARN configured for `staging` environment",
+          "advanced": true
+        },
+        {
+          "name": "AWS_PROD_OIDC_ROLE_ARN",
+          "description": "The role ARN configured for `production` environment",
+          "advanced": true
+        },
+        {
+          "name": "K8S_KUBECTL_IMAGE",
+          "description": "The Docker image used to run Kubernetes `kubectl` commands on [AWS]",
+          "default": "docker.io/alpine/k8s:1.32.1"
+        }
+      ]
     }
   ]
 }
diff --git a/templates/gitlab-ci-k8s-aws.yml b/templates/gitlab-ci-k8s-aws.yml
new file mode 100644
index 0000000..b7e5934
--- /dev/null
+++ b/templates/gitlab-ci-k8s-aws.yml
@@ -0,0 +1,82 @@
+# =====================================================================================================================
+# === Amazon Web Service template variant
+# =====================================================================================================================
+spec:
+  inputs:
+    kubectl-image:
+      description: The Docker image used to run Kubernetes `kubectl` commands on [AWS]
+      default: docker.io/alpine/k8s:1.32.1
+    aws-oidc-aud:
+      description: The `aud` claim for the JWT
+      default: $CI_SERVER_URL
+    aws-oidc-role-arn:
+      description: Default IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/)
+      default: ''
+    aws-review-oidc-role-arn:
+      description: IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `review` env _(only define to override default)_
+      default: ''
+    aws-integ-oidc-role-arn:
+      description: IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `integration` env _(only define to override default)_
+      default: ''
+    aws-staging-oidc-role-arn:
+      description: IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `staging` env _(only define to override default)_
+      default: ''
+    aws-prod-oidc-role-arn:
+      description: IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `production` env _(only define to override default)_
+      default: ''
+
+---
+variables:
+  AWS_OIDC_AUD: $[[ inputs.aws-oidc-aud ]]
+  AWS_OIDC_ROLE_ARN: $[[ inputs.aws-oidc-role-arn ]]
+  AWS_REVIEW_OIDC_ROLE_ARN: $[[ inputs.aws-review-oidc-role-arn ]]
+  AWS_STAGING_OIDC_ROLE_ARN: $[[ inputs.aws-staging-oidc-role-arn ]]
+  AWS_INTEG_OIDC_ROLE_ARN: $[[ inputs.aws-integ-oidc-role-arn ]]
+  AWS_PROD_OIDC_ROLE_ARN: $[[ inputs.aws-prod-oidc-role-arn ]]
+
+  K8S_KUBECTL_IMAGE: $[[ inputs.kubectl-image ]]
+
+.k8s-aws-sts:
+  # init Assume Role with Web Identity Configuration
+  # see: https://registry.terraform.io/providers/hashicorp/aws/latest/docs#assume-role-with-web-identity-configuration-reference
+  - echo "Installing AWS authentication"
+  - |
+    if [[ "$ENV_TYPE" ]]
+    then
+      case "$ENV_TYPE" in
+      review*)
+        env_prefix=REVIEW;;
+      integ*)
+        env_prefix=INTEG;;
+      staging*)
+        env_prefix=STAGING;;
+      prod*)
+        env_prefix=PROD;;
+      esac
+      log_info "Configuring Assume Role with Web Identity for AWS provider..."
+      export AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/web_identity_token
+      echo "${AWS_JWT}" > "$AWS_WEB_IDENTITY_TOKEN_FILE"
+      env_role_arn=$(eval echo "\$AWS_${env_prefix}_OIDC_ROLE_ARN")
+      export AWS_ROLE_ARN="${env_role_arn:-$AWS_OIDC_ROLE_ARN}"
+      export AWS_ROLE_SESSION_NAME="GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}"
+    fi
+
+.k8s-deploy:
+  id_tokens:
+    AWS_JWT:
+      aud: "$AWS_OIDC_AUD"
+  before_script:
+    - !reference [.k8s-scripts]
+    - !reference [.k8s-aws-sts]
+    - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
+    - k8s_login
+
+.k8s-cleanup: 
+  id_tokens:
+    AWS_JWT:
+      aud: "$AWS_OIDC_AUD"
+  before_script:
+    - !reference [.k8s-scripts]
+    - !reference [.k8s-aws-sts]
+    - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
+    - k8s_login
\ No newline at end of file
-- 
GitLab