如何在编程方式下从映像启动新的Amazon EC2时传递环境变量?

23

我正在使用AWS Java API RunInstance()从我的自定义AMI镜像启动一个新的EC2实例。 我如何将环境变量传递给新的EC2实例,例如数据库URL,AWS凭据等?

3个回答

13

http://alestic.com/2009/06/ec2-user-data-scripts 解释了如何使用用户数据来实现此操作。关于使用Java时需要注意的问题,请参阅AmazonEC2 launch with userdata

请注意,我看到有人提到这在Windows上不起作用,只能在Unix上使用。

[更新] 关于设置环境变量的更多数据可以在这里找到:https://forums.aws.amazon.com/message.jspa?messageID=139744

[经过大量测试] 对我而言,将环境变量回显到 /etc/environment 中最为有效,就像这样:

 reservation = connection.run_instances(image_id = image_id,
  key_name = keypair,
  instance_type = 'm1.small',
  security_groups = ['default'],
  user_data = '''#!/bin/sh\necho export foozle=barzle >> /etc/environment\n''')

然后在登录时:

ubuntu@ip-10-190-81-29:~$ echo $foozle
barzle

8

声明:我不是系统管理员!

我使用一个安全的S3存储桶,这意味着只有您正在启动的实例才可以访问该存储桶。您可以设置一个类似于以下内容的IAM角色:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",
        "s3:List*"
      ],
      "Resource": "arn:aws:s3:::some-secure-bucket/*"
    }
  ]
}

您可以将.env文件上传到存储桶中(加密存储)。然后,要在EC2实例上访问它,您可以使用AWS cli工具:

sudo apt-get install -y python-pip (for aws s3 CLI library)
sudo pip install awscli
aws s3 cp --region us-east-1 s3://some-secure-bucket/.some-dot-env-file output_file_path

您可以在代码运行时拉取此文件,或者通过将上述“cp”命令放在类似于“/etc/init.d/download_credentials.sh”的init脚本中的引导中选择使其发生。 我认为这是一个非常好的选项,用于下载每个使用AMI的实例都需要的凭据之类的内容。但是,如果您想指定每个实例的元数据,我刚刚实施了使用标签的方式,我认为这很好用。 要执行此操作,请更改上述IAM角色以更像以下内容:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",
        "s3:List*"
      ],
      "Resource": "arn:aws:s3:::some-secure-bucket/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstances",
        "ec2:DescribeTags"
      ],
      "Resource": "*"
    }
  ]
}

然后安装ec2-api-tools

sudo sed -i.dist 's,universe$,universe multiverse,' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y ec2-api-tools

现在,您应该能够通过标签获取每个实例的元数据,例如您实例的“名称”:

ec2-describe-tags --filter resource-id="$(ec2metadata --instance-id)" --filter "key=Name" | cut -f5

注意:我不擅长bash,所以我在ruby中剥离名称,但如果你喜欢的话,你可以使用tr来删除换行符!

1
很棒的解决方案,托尼。我最终做了类似的事情,但我将完整的“Instance-Init.sh”脚本放在加密存储桶中,并在实例化时拉取它。我的实际“User-Data”脚本只是安装Python、pip、was-cli,然后下载并运行“真正的”“Instance-Init.sh”脚本。你可以在这里看到我的类似问题:https://dev59.com/7l0a5IYBdhLWcg3wzbUU。但是最重要的问题是,这样做是否真的安全? - AJB
很好的问题@AJB。如果我有这个问题,我会直接与AWS支持团队交流并询问他们关于“安全性”的问题,因为那才是真正的问题。我知道对于我的使用情况来说它已经足够安全了。一个运维人员可能可以深入挖掘更多细节。此外,无关的是,我目前正在使用“用户数据”实例标签,因为我发现从实例生命周期的角度来看标签管理非常麻烦。 - Tony

5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接