14

Utilizzo CloudFormation per gestire uno stack di server Web Tomcat ma sono stufo di eseguire la gestione RAI delle AMI per le nuove versioni delle applicazioni. Mi piacerebbe andare nella direzione di Chef, ma non ho il tempo adesso. Invece, sto cercando di superare un semplice problema nell'istanza del server web: come posso scaricare una WAR "attuale" quando le nuove macchine si avviano?Come posso (in modo sicuro) scaricare un asset S3 privato su una nuova istanza EC2 con cloudinit?

Il mio pensiero era di utilizzare un bucket S3 privato e cloudinit, ma sono un po 'stordito da cosa fare con le credenziali IAM. Potrei inserirli nei dati utente del modello, ma mi dispiace non farlo, in particolare perché sono la versione che controlla quel file. L'unica alternativa a cui riesco a pensare è usare le variabili d'ambiente nell'AMI stesso. Dovrebbero essere in chiaro, ma ... eh, se riesci a entrare nella mia istanza, puoi comprimere e scaricare il mio intero webserver. Finché l'utente IAM non viene riutilizzato per nient'altro e viene ruotato regolarmente, sembra un modo ragionevole per risolvere il problema. Mi sto perdendo qualcosa? Come posso scaricare in modo sicuro un asset S3 privato usando cloudinit?

risposta

15

Amazon ha recentemente annunciato una nuova funzione in cui è possibile assegnare "ruoli IAM" alle istanze EC2. Ciò rende abbastanza facile consentire a istanze specifiche di avere il permesso di leggere risorse S3 specifiche.

Ecco il post sul blog che annuncia la nuova funzione:

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

Ecco la sezione nella documentazione EC2:

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

Ecco la sezione nella documentazione IAM:

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

I ruoli IAM rendono le credenziali disponibili per l'istanza tramite HTTP, in modo che tutti gli utenti oi processi in esecuzione nell'istanza possano visualizzarli.

+0

Esiste un completo da-inizio-to terminare l'esempio della CLI di AWS o un'esercitazione che mostra come impostare e utilizzare il meccanismo IAM? Questo riferimento sembra un esempio così complicato e completo che segue command-by-command sarebbe molto apprezzato. – pt12lol

5

Un'istanza con un ruolo IAM ha credenziali di sicurezza provvisorie che vengono automaticamente ruotate. Sono disponibili tramite http allo http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName, dove RoleName è quello che hai chiamato il tuo ruolo. Quindi sono facili da ottenere dalla tua istanza, ma scadono regolarmente.

Usarli è un po 'difficile. CloudFormation non può utilizzare direttamente le credenziali temporanee. L'AMI Amazon Linux ha installato bthon Python, ed è ora abbastanza intelligente da trovare e utilizzare automaticamente tali credenziali. Ecco una battuta si può mettere in uno script per andare a prendere un file da S3 secchio b, chiave k al file locale f:

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

boto trova e utilizza le credenziali temporanee del ruolo per voi , che lo rende davvero facile da usare.

+0

Che cos'è la "chiave k"? si tratta di un file con credenziali temporanee? – doNotCheckMyBlog

+1

Per gli utenti futuri, la chiave k è il nome del file che si desidera da S3. Se si dispone di una struttura di cartelle, la chiave sarà, foldername/file.sh – doNotCheckMyBlog

14

Per aggiornare le risposte a questa domanda un po ':

Insieme con ruoli IAM, il nuovo AWS command-line client rende il recupero tali attività banali. Prenderà automaticamente le credenziali AWS conferite tramite IAM dall'ambiente e gestirà l'aggiornamento di tali credenziali.

Ecco un esempio di recupero di un singolo asset da un secchio S3 sicuro in uno script utente-dati:

# 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 

Semplice come quello. È inoltre possibile copiare l'intero contenuto della directory da S3 e caricati, ecc. Vedere the reference material per ulteriori dettagli e opzioni.

+0

Sì, i nuovi strumenti cli sono basati su 'botocore', che sembra essere il fondamento per' boto' v3. Nel complesso [botocore] (https://github.com/boto/botocore) è un'ottima interfaccia se si conosce la struttura dell'API AWS. – Christopher

+0

Eccellente, succinta risposta @ James van Dyke. Ma ho ancora dubbi su quanto sia sicuro, illustrato nella mia domanda simile qui: http://stackoverflow.com/questions/29932355/is-it-secure-to-store-ec2-user-data-shell-scripts- in-a-s3-bucket-privato – AJB

3

Per scaricare in modo sicuro un bene S3 privato su una nuova istanza EC2, è necessario utilizzare IAM Roles for EC2 per concedere l'autorizzazione S3 necessario per l'istanza EC2, quindi chiamare aws s3 cp in del l'istanza UserDatacloudinit script per scaricare la risorsa.

Per impostare un ruolo IAM per EC2 da un modello CloudFormation, utilizzare la risorsa AWS::IAM::InstanceProfile, fa riferimento a una risorsa AWS::IAM::Role con una AssumeRolePolicyDocument delegare l'accesso a ec2.amazonaws.com, con una politica volta a grant least privilege (in questo caso, consentendo 's3:GetObject' solo per la specifica Asset S3 in fase di download).

Ecco un modello di esempio completo che scarica un bene S3 su una nuova istanza EC2 utilizzando cloudinit, tornando il suo contenuto come un 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