14

Estoy usando CloudFormation para administrar una pila de Tomcat webserver pero estoy cansado de hacer la gestión RAW de AMI para nuevas versiones de aplicaciones. Me gustaría moverme en la dirección del Chef pero no tengo el tiempo ahora mismo. En cambio, intento conquistar un problema simple en la creación de instancias del servidor web: ¿cómo puedo descargar un WAR "actual" cuando las nuevas máquinas se aceleran?¿Cómo puedo (de forma segura) descargar un activo privado S3 en una nueva instancia EC2 con cloudinit?

Mi idea era utilizar un bucket S3 privado y cloudinit, pero estoy un poco perplejo sobre qué hacer con las credenciales de IAM. Podría ponerlos en los datos de usuario de la plantilla, pero detestaba hacerlo, particularmente porque soy la versión que controla ese archivo. La única alternativa que puedo pensar es usar variables de entorno en el AMI mismo. Tendrían que ser de texto plano, pero ... eh, si puedes entrar en mi instancia, puedes comprimir y descargar todo mi servidor web. Siempre que el usuario de IAM no se reutilice para nada más y se gire con regularidad, parece una forma razonable de resolver el problema. ¿Me estoy perdiendo algo? ¿Cómo puedo descargar de forma segura un activo privado S3 utilizando cloudinit?

Respuesta

15

Amazon anunció recientemente una nueva función en la que puede asignar "roles IAM" a sus instancias EC2. Esto hace que sea bastante fácil permitir que instancias específicas tengan permiso para leer recursos específicos de S3.

Aquí es su blog anunciando la nueva característica:

http://aws.typepad.com/aws/2012/06/iam-roles-for-ec2-instances-simplified-secure-access-to-aws-service-apis-from-ec2.html

Aquí está la sección de la documentación EC2:

http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/UsingIAM.html#UsingIAMrolesWithAmazonEC2Instances

Aquí está la sección de la documentación IAM:

http://docs.amazonwebservices.com/IAM/latest/UserGuide/WorkingWithRoles.html

Los roles de IAM hacen que las credenciales estén disponibles para la instancia a través de HTTP, por lo que cualquier usuario o proceso que se ejecute en la instancia puede verlas.

+0

¿Hay alguna completa del-principio-a- finalice el ejemplo o tutorial de AWS CLI que muestra cómo configurar y usar el mecanismo IAM? Estas referencias se ven tan complicadas y el ejemplo completo siguiente al comando por comando sería muy apreciado. – pt12lol

5

Una instancia con un rol de IAM tiene credenciales de seguridad temporales que se rotan automáticamente. Están disponibles a través de http en http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName, donde RoleName es lo que usted llamó su función. Así que son fáciles de obtener de su instancia, pero caducan regularmente.

Su uso es un poco difícil. CloudFormation no puede usar credenciales temporales directamente. Amazon Linux AMI tiene el boto de Python instalado, y ahora es lo suficientemente inteligente como para encontrar y usar esas credenciales automáticamente. Aquí hay una sola línea que puede poner en una secuencia de comandos para obtener un archivo desde S3 cubo b, clave k a archivo local f:

python -c "import boto;boto.connect_s3().get_bucket('b').get_key('k').get_contents_to_filename('f')" 

boto encuentra y utiliza las credenciales temporales del papel para usted , lo que lo hace realmente fácil de usar

+0

¿Qué es la "clave k"? ¿Es un archivo con credenciales temporales? – doNotCheckMyBlog

+1

Para futuros usuarios, la clave k es el nombre de archivo que desea de S3. Si tiene una estructura de carpetas, la clave será, nombre de carpeta/archivo.sh – doNotCheckMyBlog

14

Para actualizar las respuestas a esta pregunta un poco:

Junto con las funciones de IAM, el nuevo AWS command-line client hace ir a buscar estos activos trivial. Automáticamente extraerá las credenciales de AWS otorgadas a través de IAM del entorno y manejará la actualización de esas credenciales.

He aquí un ejemplo de traer un solo activo a partir de un depósito de S3 seguro en una escritura de datos de usuario:

# Install the AWS command-line tools 
pip install awscli 

# Fetch the asset 
aws s3 cp --region us-east-1 s3://my-private-bucket/a-folder/an-asset.zip /some/destination 

Tan simple como eso. También puede copiar todo el contenido del directorio desde S3 y cargarlo, etc. Consulte the reference material para obtener más detalles y opciones.

+0

Sí, las nuevas herramientas cli se basan en 'botocore', que parece ser la base para' boto' v3. En general, [botocore] (https://github.com/boto/botocore) es una excelente interfaz si conoce la estructura de la API de AWS. – Christopher

+0

Respuesta excelente y breve @James van Dyke. Pero todavía tengo dudas sobre cuán seguro es esto, ilustrado en mi pregunta similar aquí: http://stackoverflow.com/questions/29932355/is-it-secure-to-store-ec2-user-data-shell-scripts- in-a-private-s3-bucket – AJB

3

Para descargar de forma segura un activo S3 privada que da una nueva instancia EC2, se debe utilizar IAM Roles for EC2 para conceder el permiso necesario S3 a la instancia EC2, a continuación, llamar aws s3 cp en su instancia de UserDatacloudinit script descargar el activo.

Para configurar un papel IAM para EC2 partir de una plantilla CloudFormation, utilizar el recurso AWS::IAM::InstanceProfile, haciendo referencia a un recurso AWS::IAM::Role con un AssumeRolePolicyDocument delegar el acceso a ec2.amazonaws.com, con una política destinada a grant least privilege (en este caso, lo que permite 's3:GetObject' sólo para la específica Activo de S3 que se está descargando).

Aquí está un ejemplo de plantilla completa que descarga un activo S3 a una nueva instancia EC2 usando cloudinit, volviendo su contenido como Stack Output:

Launch Stack

Description: (securely) download a private S3 asset onto a new EC2 instance with cloudinit 
Parameters: 
    S3Bucket: 
    Description: S3 bucket name 
    Type: String 
    S3Key: 
    Description: S3 object key 
    Type: String 
Mappings: 
    # amzn-ami-hvm-2016.09.1.20161221-x86_64-gp2 
    RegionMap: 
    us-east-1: 
     "64": "ami-9be6f38c" 
Resources: 
    EC2Role: 
    Type: AWS::IAM::Role 
    Properties: 
     AssumeRolePolicyDocument: 
     Version: 2012-10-17 
     Statement: 
     - Effect: Allow 
      Principal: {Service: [ ec2.amazonaws.com ]} 
      Action: ["sts:AssumeRole"] 
     Path:/
     Policies: 
     - PolicyName: EC2Policy 
     PolicyDocument: 
      Version: 2012-10-17 
      Statement: 
      - Effect: Allow 
      Action: ['s3:GetObject'] 
      Resource: !Sub 'arn:aws:s3:::${S3Bucket}/${S3Key}' 
    RootInstanceProfile: 
    Type: AWS::IAM::InstanceProfile 
    Properties: 
     Path:/
     Roles: [ !Ref EC2Role ] 
    WebServer: 
    Type: AWS::EC2::Instance 
    Properties: 
     ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", 64 ] 
     InstanceType: m3.medium 
     IamInstanceProfile: !Ref RootInstanceProfile 
     UserData: 
     "Fn::Base64": 
      !Sub | 
      #!/bin/bash 
      DATA=$(aws s3 cp s3://${S3Bucket}/${S3Key} -) 
      /opt/aws/bin/cfn-signal \ 
       -e $? \ 
       -d "$DATA" \ 
       '${Handle}' 
    Handle: 
    Type: AWS::CloudFormation::WaitConditionHandle 
    Wait: 
    Type: AWS::CloudFormation::WaitCondition 
    Properties: 
     Handle: !Ref Handle 
     Timeout: 300 
Outputs: 
    Result: 
    Value: !GetAtt Wait.Data 
Cuestiones relacionadas