Asegura el acceso de Jenkins a AWS (parte II)

 In aws, DevOps, Security

Configuración recomendada

Si has seguido los pasos del post previo: Asegurar el acceso de Jenkins a AWS (parte I), tienes:

  • Usuarios de IAM que solo pueden asumir un rol.
  • Claves de acceso de AWS para aquellos usuarios almacenados en Jenkins (utilizando el complemento de credenciales de AWS).
  • Un dispositivo MFA asignado a cada usuario.
  • Una condición que obliga el uso de MFA al asumir roles.

Ejemplo de pipeline

Con esto, ahora podemos ejecutar una pipeline que aproveche esta configuración. Algo como:

def getAWSUser() {
  wrap([$class: "BuildUser"]) {
    return env.BUILD_USER_ID
  }
}

def getCredentialsId() {
  wrap([$class: "BuildUser"]) {
    return env.BUILD_USER_ID
  }
}

def assumeRole(String credentials, String userName,
  String accountId = "YOUR_AWS_ACCOUNT_ID", String role = "role_to_be_assumed") {
  def String trustedAccount = "YOUR_AWS_ACCOUNT_ID"

  def mfa = input(
    message: "Enter MFA Token",
    parameters: [[$class: 'StringParameterDefinition', name: 'mfa', trim: true]]
  )

  withCredentials([[
    $class: 'AmazonWebServicesCredentialsBinding',
    credentialsId: "${credentials}",
    accessKeyVariable: 'AWS_ACCESS_KEY_ID',
    secretKeyVariable: 'AWS_SECRET_ACCESS_KEY'
  ]]) {
    return sh(script: """
      aws sts assume-role \
        --role-arn arn:aws:iam::${accountId}:role/${role} \
        --serial-number arn:aws:iam::${trustedAccount}:mfa/${userName} \
        --query 'Credentials' \
        --token-code ${mfa} \
        --role-session-name ${userName}
    """, returnStdout: true)
  }
}

pipeline {
  agent any

  stages {
    stage('Setup') {
      steps {
        script {
          AWSUser = getAWSUser()
          credentialsId = getCredentialsId()
        }
      }
    }

    stage('Get credentials') {
      steps {
        script {
          jsonCreds = assumeRole("${credentialsId}", "${AWSUser}")
          creds = readJSON text: "${jsonCreds}"
        }
      }
    }

    stage('Use credentials') {
      steps {
        withEnv([
            "AWS_ACCESS_KEY_ID=${creds.AccessKeyId}",
            "AWS_SECRET_ACCESS_KEY=${creds.SecretAccessKey}",
            "AWS_SESSION_TOKEN=${creds.SessionToken}"
          ]) {
            sh """
              aws sts get-caller-identity
            """
        }
      }
    }
  }
}

Al ejecutar la pipeline, Jenkins te pedirá que ingreses el código de MFA para asumir el rol deseado:

A continuación, usa esas credenciales para realizar cualquier cosa relacionada con AWS:

Puntos Clave

  • Si has seguido mi consejo, el nombre de usuario de IAM y el ID de credenciales serán los mismos que el nombre de usuario de Jenkins. De lo contrario, tendrás que modificar las funciones getAWSUser y / o getCredentialsId en consecuencia.
  • Este ejemplo asume un rol privilegiado en la misma cuenta que el usuario de IAM, pero esta configuración se puede usar para asumir un rol en otra cuenta. Simplemente pasa el ID de la cuenta de destino como parámetro al llamar a la función assumeRole.
Recent Posts

Leave a Comment

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.