Как я могу (безопасно) загрузить частный актив S3 в новый инстанс EC2 с помощью cloudinit?

Я использую CloudFormation для управления стеком веб-сервера Tomcat, но устал от необработанного управления AMI для новых версий приложений. Я хотел бы двигаться в направлении Chef, но сейчас нет времени. Вместо этого я пытаюсь решить простую проблему создания экземпляра веб-сервера: как я могу загрузить «текущий» WAR, когда раскручиваются новые машины?

Я думал использовать частную корзину S3 и cloudinit, но я немного озадачен тем, что делать с учетными данными IAM. Я мог бы поместить их в пользовательские данные шаблона, но мне не хочется этого делать, особенно потому, что я контролирую версию этого файла. Единственная альтернатива, о которой я могу думать, - это использовать переменные среды в самом AMI. Они должны быть открытым текстом, но... Эх, если бы вы могли проникнуть в мой экземпляр, вы могли бы заархивировать и загрузить весь мой веб-сервер. Пока пользователь IAM не используется повторно ни для чего другого и регулярно ротируется, это кажется разумным способом решения проблемы. Я что-то упустил? Как я могу безопасно загрузить частный актив S3 с помощью cloudinit?


person Christopher    schedule 06.07.2012    source источник


Ответы (4)


Amazon недавно анонсировала новую функцию, с помощью которой вы можете назначать «роли IAM» своим инстансам EC2. Это позволяет довольно легко разрешить определенным экземплярам иметь разрешение на чтение определенных ресурсов S3.

Вот их сообщение в блоге, объявляющее о новой функции:

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

Вот раздел в документации EC2:

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

Вот раздел в документации IAM:

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

Роли IAM делают учетные данные доступными для экземпляра через HTTP, поэтому их могут видеть любые пользователи или процессы, запущенные в экземпляре.

person Eric Hammond    schedule 06.07.2012
comment
Есть ли какой-либо полный пример или руководство AWS CLI от начала до конца, показывающее, как настроить и использовать механизм IAM? Эти ссылки выглядят такими сложными, и полный пример, следующий за командой, был бы очень признателен. - person pt12lol; 11.05.2017

Чтобы немного обновить ответы на этот вопрос:

Наряду с ролями IAM новый клиент командной строки AWS позволяет получение этих активов тривиально. Он автоматически извлечет учетные данные AWS, предоставленные через IAM, из среды и обработает обновление этих учетных данных.

Вот пример извлечения одного ресурса из безопасного сегмента S3 в скрипте пользовательских данных:

# 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

Просто как тот. Вы также можете скопировать все содержимое каталога из S3 и загрузить его и т. д. См. справочный материал для получения более подробной информации и вариантов.

person James van Dyke    schedule 02.10.2013
comment
Да, новые инструменты cli основаны на botocore, который, по-видимому, является основой для boto v3. В целом botocore — отличный интерфейс, если вы знаете структуру AWS API. - person Christopher; 03.10.2013
comment
Отличный, лаконичный ответ @James van Dyke. Но у меня все еще есть сомнения относительно того, насколько это безопасно, как показано в моем аналогичном вопросе здесь: stackoverflow.com/questions/29932355/ - person AJB; 02.05.2015

Экземпляр с ролью IAM имеет временные учетные данные безопасности, которые автоматически меняются. Они доступны через http по адресу http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName, где RoleName — это то, что вы назвали своей ролью. Так что их легко получить из вашего инстанса, но срок их действия регулярно истекает.

Использование их немного сложно. CloudFormation не может напрямую использовать временные учетные данные. В Amazon Linux AMI установлен Python boto, и теперь он достаточно умен, чтобы автоматически находить и использовать эти учетные данные для вас. Вот однострочный скрипт, который вы можете добавить в скрипт для извлечения файла из корзины S3 b, ключ k в локальный файл f:

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

boto находит и использует для вас временные учетные данные роли, что делает его очень простым в использовании.

person Charles Engelke    schedule 20.12.2012
comment
Что такое ключ k? это файл с временными учетными данными? - person TeaCupApp; 09.09.2013
comment
Для будущих пользователей ключ k — это имя файла, которое вы хотите от S3. Если у вас есть структура папок, то ключ будет иметь имя папки/файл.sh - person TeaCupApp; 09.09.2013

Чтобы безопасно загрузить частный ресурс S3 в новый экземпляр EC2, следует использовать Роли IAM для EC2, чтобы предоставить необходимое разрешение S3 для вашего экземпляра EC2, затем вызовите aws s3 cp в вашем экземпляре UserData cloudinit script для загрузки актива.

Чтобы настроить роль IAM для EC2 из шаблона CloudFormation, используйте AWS::IAM::InstanceProfile, ссылающийся на AWS::IAM::Role ресурс с AssumeRolePolicyDocument делегированием доступа к ec2.amazonaws.com, с политикой, предназначенной для предоставить минимальные привилегии (в данном случае разрешая 's3:GetObject' только для конкретного загружаемого ресурса S3).

Вот полный пример шаблона, который загружает ресурс S3 в новый инстанс EC2 с помощью cloudinit, возвращая его содержимое в виде Вывод стека:

Запуск стека

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
person wjordan    schedule 05.01.2017