Gitlab CI에서 AWS IAM 역할에 대한 액세스 보호

Gitlab CI 구성에서 하루에 몇 개의 액세스 및 비밀 키가 변수로 저장됩니까?
AWS access key가 Gitlab에 저장되면 클라우드 인프라 외부에 자격 증명을 저장하는 모든 보안 문제(액세스, 권한 부여, 키 순환, 수명, 파괴, 위치 등)에 직면하게 됩니다.

개발자가 Gitlab CI에 AWS 자격 증명을 저장하는 두 가지 일반적인 이유가 있습니다.
  • 그들은 shared runners를 사용합니다.
  • specific runners 클러스터에 배포된 Amazon Elastic Kubernetes Service를 사용하지만 IAM Roles for Service Accounts 기능을 사용하지 않거나 알지 못합니다.

  • Gitlab CI에서 AWS 액세스 키를 계속 사용하고 Vault 및 Forseti와 같은 외부 도구로 키를 보호할 수 있지만 이렇게 하면 관리할 도구가 추가됩니다.

    AWS가 고객에게 제안하는 대안은 IRSA(서비스 계정에 대한 IAM 역할) 기능을 사용하는 것입니다.

    IRSA 기능을 사용하면 특정 러너와 연결된 Kubernetes Service AccountAWS IAM Role에 바인딩할 수 있습니다.

    IRSA와 협력



    첫 번째 단계는 EKS devops 클러스터를 생성하고 구성하는 것입니다.
  • eksctl을 사용하여 EKS 클러스터[1]를 생성하는 것으로 시작합니다.

  • export AWS_PROFILE=<AWS_PROFILE>
    export AWS_REGION=eu-west-1
    export EKS_CLUSTER_NAME=devops
    export EKS_VERSION=1.19
    
    eksctl create cluster \
     --name $EKS_CLUSTER_NAME \
     --version $EKS_VERSION \
     --region $AWS_REGION \
     --managed \
     --node-labels "nodepool=dev"
    


  • 클러스터에 대한 IAM OIDC 자격 증명 공급자 생성

  • eksctl utils associate-iam-oidc-provider --cluster=$EKS_CLUSTER_NAME --approve
    
    ISSUER_URL=$(aws eks describe-cluster \
                           --name $EKS_CLUSTER_NAME \
                           --query cluster.identity.oidc.issuer \
                           --output text)
    


  • 클러스터와 통신하도록 구성kubectl:

  • aws eks --region $AWS_REGION update-kubeconfig --name $EKS_CLUSTER_NAME
    


  • Kubernetes 서비스 계정에 사용할 네임스페이스를 생성합니다.

  • kubectl create namespace dev
    


  • 특정 실행기에 사용할 Kubernetes 서비스 계정을 생성합니다.

  • kubectl create serviceaccount --namespace dev app-deployer
    


  • 둘 간의 IAM 정책 바인딩을 사용하여 Kubernetes 서비스 계정이 IAM 역할을 가장하도록 허용합니다. 이 바인딩을 통해 Kubernetes 서비스 계정은 IAM 역할로 작동할 수 있습니다.

  • ISSUER_HOSTPATH=$(echo $ISSUER_URL | cut -f 3- -d'/')
    
    AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
    
    PROVIDER_ARN="arn:aws:iam::$AWS_ACCOUNT_ID:oidc-provider/$ISSUER_HOSTPATH"
    
    cat > trust-policy.json << EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "$PROVIDER_ARN"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "${ISSUER_HOSTPATH}:sub": "system:serviceaccount:dev:app-deployer",
              "${ISSUER_HOSTPATH}:aud": "sts.amazonaws.com"
            }
          }
        }
      ]
    }
    EOF
    
    ROLE_NAME=eks-cluster-role
    
    aws iam create-role \
              --role-name $ROLE_NAME  \
              --assume-role-policy-document file://trust-policy.json
    
    EKS_ROLE_ARN=$(aws iam get-role \
                            --role-name $ROLE_NAME \
                            --query Role.Arn --output text)
    


  • IAM 역할 ARN을 사용하여 Kubernetes 서비스 계정에 eks.amazonaws.com/role-arn=$EKS_ROLE_ARN 주석을 추가합니다.

  • kubectl annotate serviceAccount app-deployer -n dev eks.amazonaws.com/role-arn=$EKS_ROLE_ARN
    


    You could also use eksctl create iamserviceaccount [..] [2]





    Gitlab 실행기에 KSA 할당



    다음 단계는 KSA를 Gitlab 실행기에 할당하는 것입니다.
  • Helm을 설치하여 시작합니다.

  • curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.sh
    


  • Gitlab Helm 패키지를 추가합니다.

  • helm repo add gitlab https://charts.gitlab.io
    


  • 러너 구성:

  • 파일 생성values.yaml:

    imagePullPolicy: IfNotPresent
    gitlabUrl: https://gitlab.com/
    runnerRegistrationToken: "<REGISTRATION_TOKEN>"
    unregisterRunners: true
    terminationGracePeriodSeconds: 3600
    concurrent: 10
    checkInterval: 30
    rbac:
      create: true
    metrics:
      enabled: true
    runners:
      image: ubuntu:18.04
      locked: true
      pollTimeout: 360
      protected: true
      serviceAccountName: app-deployer
      privileged: false
      namespace: dev
      builds:
        cpuRequests: 100m
        memoryRequests: 128Mi
      services:
        cpuRequests: 100m
        memoryRequests: 128Mi
      helpers:
        cpuRequests: 100m
        memoryRequests: 128Mi
      tags: "k8s-dev-runner"
      nodeSelector: 
        nodepool: dev
    


    You can find the description of each attribute in the Gitlab runner charts repository [3]


  • Project -> Settings -> CI/CD -> Runners 섹션의 Setup a specific Runner manually에서 Gitlab 등록 토큰을 가져옵니다.
  • 러너 설치:

  • helm install -n dev app-dev-runner -f values.yaml gitlab/gitlab-runner
    




    Gitlab CI에서 특정 러너 사용



    Gitlab CI에서 첫 번째 파이프라인을 실행하기 전에 앞서 생성한 IAM 역할에 Kubernetes 클러스터 관리자 권한을 추가해 보겠습니다.

    cat > eks-admin-policy.json << EOF
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "eksadministrator",
                "Effect": "Allow",
                "Action": [
                     "eks:*",
                     "cloudformation:*",
                     "ec2:*",
                     "ssm:*",
                     "iam:*"
    
                ],
                "Resource": "*"
            }
        ]
    }
    EOF
    
    aws iam  put-role-policy \
    --role-name $ROLE_NAME \
    --policy-name eks-admin-policy \
    --policy-document file://eks-admin-policy.json
    


    Note: This policy is used as an example. AWS recommends you to use fine grained permissions.



    이제 파이프라인.gitlab-ci.yaml을 실행할 수 있습니다.

    stages:
      - dev
    
    before_script:
        - yum install -y tar gzip
        - curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
        - mv /tmp/eksctl /usr/local/bin
    infra:
      stage: dev
      image: 
        name: amazon/aws-cli
      script: 
        - eksctl create cluster --name=business --region=eu-west-1 --managed --instance-types t3.medium
      tags:
        - k8s-dev-runner
    


    이 작업은 eksctl 를 사용하여 AWS 계정에 EKS 클러스터를 생성합니다. prod 환경에 대해 동일한 단계를 따를 수 있습니다.



    결론



    이 메커니즘은 IAM 역할 리소스에 대한 엔드 투 엔드 보안을 보장합니다. 저녁에 IAM 역할을 삭제하고 근무일 아침에 다시 생성하는 cron 작업을 쉽게 생성할 수 있습니다.

    질문이나 의견이 있으시면 언제든지 의견을 남겨주세요.

    그렇지 않으면 Gitlab CI 변수에서 액세스 및 비밀 키를 제거하고 IRSA가 구성된 EKS에서 특정 러너를 사용하도록 설득했으면 합니다.

    그건 그렇고, 주저하지 말고 동료들과 공유하십시오 😊

    읽어 주셔서 감사합니다!

    선적 서류 비치



    [1] https://aws.amazon.com/fr/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/
    [2] https://eksctl.io/usage/iamserviceaccounts
    [3] https://gitlab.com/gitlab-org/charts/gitlab-runner/-/blob/main/values.yaml

    좋은 웹페이지 즐겨찾기