【问题标题】:EC2 User Data not working via python boto commandEC2 用户数据无法通过 python boto 命令工作
【发布时间】:2017-05-25 22:08:51
【问题描述】:

我正在尝试启动一个实例,让一个脚本在它作为用户数据的一部分首次启动时运行。使用了以下代码(python boto3 库):

import boto3
ec2 = boto3.resource('ec2')
instance = ec2.create_instances(DryRun=False, ImageId='ami-abcd1234', MinCount=1, MaxCount=1, KeyName='tde', Placement={'AvailabilityZone': 'us-west-2a'}, SecurityGroupIds=['sg-abcd1234'], UserData=user_data, InstanceType='c3.xlarge', SubnetId='subnet-abcd1234')

我一直在使用 user_data 并没有成功。我一直在尝试将一些字符串回显到现有目录中的新文件。以下是我尝试的最新版本。

user_data = '''
    #!/bin/bash
    echo 'test' > /home/ec2/test.txt
    '''

ami 是基于 CentOS 的私有 AMI。我已经在服务器上本地测试了这些命令并让它们工作。但是当我在 userdata 上使用相同的命令(稍微调整以匹配 userdata 格式)时,它不起作用。实例启动成功,但我指定的文件不存在。

我查看了其他示例 (https://github.com/coresoftwaregroup/boto-examples/blob/master/32-create-instance-enhanced-with-user-data.py),甚至复制了它们的命令。

感谢您的帮助!谢谢:)

【问题讨论】:

    标签: python amazon-web-services amazon-ec2 user-data


    【解决方案1】:

    为了将用户数据识别为脚本,第一个个字符必须是 #!(至少对于 Linux 实例)。

    但是,您的 user_data 变量被定义为:

    "\n    #!/bin/bash\n    echo 'test' > /home/ec2/test.txt\n    "
    

    你应该这样定义它:

    user_data = '''#!/bin/bash
    echo 'test' > /tmp/hello'''
    

    产生:

    "#!/bin/bash\necho 'test' > /tmp/hello"
    

    这可以正常工作。

    所以,这是最终产品:

    import boto3
    
    ec2 = boto3.resource('ec2')
    
    user_data = '''#!/bin/bash
    echo 'test' > /tmp/hello'''
    
    instance = ec2.create_instances(ImageId='ami-abcd1234', MinCount=1, MaxCount=1, KeyName='my-key', SecurityGroupIds=['sg-abcd1234'], UserData=user_data, InstanceType='t2.nano', SubnetId='subnet-abcd1234')
    

    登录后:

    [ec2-user@ip-172-31-2-151 ~]$ ls /tmp
    hello  hsperfdata_root
    

    【讨论】:

    • 仍然没有工作 - 我更新了我的 user_data 以匹配你的:>>> user_data = '''#!/bin/bash ... echo 'test' > /tmp/hello'''我启动了一个服务器并登录: [root@ip-172-31-26-28 ~]# ll -tr /tmp/ total 8 drwxr-xr-x 2 elasticsearch elasticsearch 4096 Feb 16 2016 elasticsearch drwxr-xr-x 2 elasticsearch elasticsearch 4096 2016 年 2 月 17 日 jna--1985354563 [root@ip-172-31-26-28 ~]# 干杯
    • 它没有解决我的问题。如果您阅读了我对您的第一个答案的评论,您会看到我尝试了您的建议,但仍然无效。有什么想法吗?
    • 如果您通过 EC2 管理控制台启动并手动输入用户数据,用户数据是否适用于该 AMI? AMI 可能未配置为 cloud-init
    • 谢谢约翰!欣赏后续。我在 curl 169.254.169.254/latest/user-data 时看到了用户数据。不幸的是,它没有执行它(我重新运行了与您在第一个答案中建议的相同的命令)。有关如何为 cloud-init + 配置实例然后将其保存为 AMI 映像的任何有用链接?如果那是要走的路。干杯!
    • 我在上面添加了一个完整的示例,输出显示它有效。如果它对您不起作用,那么问题在于未为 cloud-init 配置 AMI。 (默认情况下,所有 AWS Linux AMI 都配置了 cloud-init。)我不确定您所说的“为 cloud-init + 配置实例 + 然后将其保存为 AMI 映像”是什么意思——用户数据未保存在AMI,在实例启动时指定。或者,您可以将 Linux 配置为在启动时运行命令,而不涉及用户数据。 (在别处搜索以了解方法!)
    【解决方案2】:

    也许你的脚本没有工作,因为你输入了错误的用户路径。

    正确的用户路径是/home/ec2-user,而不是您脚本中假设的/home/ec2

    试试这个作为用户数据:

    user_data = '''
        #!/bin/bash
        echo 'test' > /home/ec2-user/test.txt
        '''
    

    【讨论】:

      【解决方案3】:

      我认为您需要指定实例配置文件。看看这个页面:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-api-cli

      执行此操作的步骤包括:

      • 创建角色
      • 将适当的策略文档附加到该角色(注意:示例中使用的 AmazonEC2FullAccess 策略可能不是它,我只是还没有找到更好的替代方案)
      • 创建实例配置文件
      • 将角色附加到实例配置文件
      • 使用实例配置文件创建实例

      另外,正如其他答案中提到的那样,以您的用户数据开头

      #!/bin/bash

      这是一个“简化”的代码 sn-p,我正在使用它来做同样的事情。这会跳过其他初始化步骤,例如选择机器映像和设置安全组等。

      iam_client = boto3.client('iam')
      
      # create assume role policy document
      assume_role_policy_document = json.dumps({
          "Version": "2012-10-17",
          "Statement": [
              {
              "Effect": "Allow",
              "Principal": {
                  "Service": "ec2.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
              }
          ]
      })
      
      # create ec2 full access role
      role_response = iam_client.create_role(
          RoleName='ec2_full_access_role',
          AssumeRolePolicyDocument=assume_role_policy_document,
          Description='AmazonEC2FullAccess',
          MaxSessionDuration=3600,
      )
      
      # get policy arm
      policy_arn = policies_df[policies_df.PolicyName=='AmazonEC2FullAccess'].Arn.iloc[0]
      
      # attach policy
      role_attach_response = iam_client.attach_role_policy(
          RoleName='ec2_full_access_role', 
          PolicyArn=policy_arn
      )
      
      # create instance profile
      instance_profile_response = iam_client.create_instance_profile(
          InstanceProfileName='ec2_instance_profile',
      )
      
      # attach role to instance profile
      attach_role_response = iam_client.add_role_to_instance_profile(
          InstanceProfileName='ec2_instance_profile',
          RoleName='ec2_full_access_role'
      )
      
      # define user data
      user_data = """#!/bin/bash
      touch test.txt
      """
      
      # create instance
      instance_params = {
          'ImageId': image_id,
          'InstanceType': instance_type,
          'KeyName': key_name,
          'SecurityGroups': (sg_name, ),
          'UserData': user_data,
          'IamInstanceProfile':{'Name': 'ec2_instance_profile'},
          'MinCount': 1, 
          'MaxCount': 1
      }
      instances = ec2_res.create_instances(**instance_params)
      

      【讨论】:

        猜你喜欢
        • 2015-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-28
        • 1970-01-01
        • 1970-01-01
        • 2011-03-06
        • 2016-03-08
        相关资源
        最近更新 更多