使用AWS Elastic Beanstalk和Ruby容器设置私有Github访问

时间:2012-11-20 15:10:41

标签: ruby-on-rails ruby amazon-web-services elastic-beanstalk

通过recent tutorial使用Git设置AWS Elastic Beanstalk进行Ruby部署,我只是从我的CI服务器设置了一个Elastic Beanstalk环境。但是,应用程序无法启动。我浏览了日志,发现bundle install失败并显示错误消息。

  

获取git@github.com:example / private-repository.git   主机密钥验证失败。   致命:远程端意外挂断   [31mGit错误:目录/ var / app / ondeck中的命令git clone 'git@github.com:example/private-repository.git' "/var/app/ondeck/vendor/cache/ruby/1.9.1/cache/bundler/git/private-repository-e4bbe6c2b13bb62664e39e345c1b01d80017934c" --bare --no-hardlinks失败。[0m

我的Rails应用程序的

Gemfile包含对我在Github上拥有的几个私有存储库上托管的gemified插件的引用。像

这样的东西
  

gem'partgemname',:git => 'git@github.com:例如/私人repository.git'

我遇到了与Capistrano部署类似的问题,这些问题通过设置ssh_options[:forward_agent] = true来解决。

AWS Elastic Beanstalk Ruby容器通过位于.config下的自定义.ebextensions文件支持自定义配置。在这种情况下,设置SSH转发代理会有所帮助吗?在启动Elastic Beanstalk环境时,还有其他替代方法可以访问私有Github存储库吗?

更新1: 我刚刚检查了发起bundle install的用户。发现脚本/opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.shbundle install用户身份root启动。我尝试在/root/.ssh下创建一个SSH密钥,并将其pub-key添加到该存储库的Github Deploy密钥。到目前为止没有运气。现在将尝试在我的Github上的用户帐户中添加一个SSH pub-key,以便它适用于通过我的Github帐户访问的所有私有存储库。

5 个答案:

答案 0 :(得分:33)

经过一天的努力,我终于通过使用.config文件启用了我的组织的私有GitHub repos和Elastic Beanstalk。我正在使用Python和pip,但它也适用于EB上的其他软件包安装程序。

rhetonik的ssh-agent + ssh-add方法对我来说根本不起作用,所以我选择设置一个ssh配置文件。

这是我的.ebextensions/3-pip-install-from-github.config文件:

files:
    "/root/.ssh/config":
        owner: root
        group: root
        mode: "000600"
        content: |
            Host github.com
                User git
                Hostname github.com
                IdentityFile /root/.ssh/github
    "/root/.ssh/known_hosts":
        owner: root
        group: root
        mode: "000644"
        content: |
            #
            # paste output of `ssh-keyscan -H github.com` here
            #

commands:
    01-command:
        command: sudo aws s3 cp s3://bucket-with-your-github-ssh-key/github /root/.ssh
    02-command:
        command: sudo chmod 600 /root/.ssh/github

粗略的指示:

  • 设置EB实例可访问的S3存储桶。在该存储桶内部,存储SSH密钥,允许访问您要通过pipnpmbundle等访问的GitHub存储库。使用sudo aws s3 cp复制该密钥部署到您的EB实例上。 sudo是必要的,因为EB脚本使用root而非ec2-user

  • 此ebextensions配置文件还会在您的EB实例上创建2个文件。 /root/.ssh/config告诉ssh(由pipgit调用)使用您从S3复制的密钥。将ssh-keyscan -H github.com的输出粘贴到/root/.ssh/known_hosts将预先验证您的EB实例上的ssh是否实际与GitHub通信以避免MITM攻击。这比在StrictHostKeyChecking中停用/root/.ssh/config要好。

以下是requirements.txt的{​​{1}}个文件:

pip

在运行Beaker==1.7.0 Flask==0.10.1 Jinja2==2.7.3 MarkupSafe==0.23 # [...] git+ssh://git@github.com/myorganization/myprivaterepo.git@0.0.142 时,您可eb-deploy确保一切顺利进行。

答案 1 :(得分:10)

这是我最终如何做到的。这都是为负责bundle install阶段的用户设置SSH密钥。

  1. 在AWS Elastic Beanstalk中为应用程序启动环境
  2. 可选 - 登录Amazon EC2控制台并将实例类型更改为所需的值
  3. 更新SSH密钥对名称以启用远程SSH登录。 (我确信在启动环境时必须有一种方法来指定实例类型和SSH密钥对名称)
  4. 在EC2控制台或CLI中查找新启动的实例,请注意此实例的完全限定域名(FQDN)。 EB实例与您使用Amazon EC2创建的任何其他实例类似。通过SSH登录到此实例。
  5. 执行以下命令为root用户创建SSH密钥
      

    $ sudo su - root

         

    $ ssh-keygen -t rsa -C“some-email@yourdomain.com”

  6.   
  7. 编辑.bash_profile以显式启动ssh-agent并添加新生成的SSH密钥。添加以下行(这可能看起来没必要,我只是为了确保这样做)

      

    eval`ssh-agent

         

    eval ssh-add ~/.ssh/id_rsa

  8. 请注意SSH公钥E.g。:~/.ssh/id_rsa.pub并将其添加到可以访问私有存储库的Github帐户的SSH密钥集

  9. 此时,您的实例可以访问您的私有Github存储库。您可以通过以git clone用户身份登录来对这些存储库发出root来测试此问题。

  10. 使用标准方法

  11. 从此实例中创建AMI
  12. 返回您的AWS Elastic Beanstalk仪表板,在您的应用程序环境中查找Edit Configuration选项。在Server标签中,查找允许您指定Custom AMI的选项。使用新创建的AMI ID E.g。:ami-4324fd4

  13. 更新此字段
  14. 点击Apply Changes保存配置。 AWS Elastic Beanstalk将开始在您的环境中部署新实例并终止旧实例。这是为了确保所有自动扩展的实例都具有私有Github访问所需的白名单SSH密钥。

  15. 完成上述步骤后,您可以继续使用git aws.push部署Rails应用程序

    希望这有助于其他被困的人。我很高兴看到比这个更优雅的解决方案。

答案 2 :(得分:4)

如果您赶时间,并且您的应用程序存储库也是私有的,您可以创建一个额外的Github用户帐户,并为包含该gem的repo分配只读权限。

然后使用新帐户的凭据为捆绑商提供https网址:

gem 'somegemname', git: "https://username:password@github.com/example/privaterepository"

答案 3 :(得分:0)

使用GitHub进行身份验证有两种方法。我建议您将个人GitHub帐户与私人GitHub仓库相关联。

第一种方法将您在本地使用的相同ssh凭据传递给远程GitHub存储库中的推送,拉取等等 - 您上传了个人帐户的公钥,这就是GitHub使用的。要在其他服务器上运行时使其工作,您需要运行ssh-agent并使用ssh-add将密钥添加到代理 - 然后您的个人GitHub凭据可用于执行git命令。 / p>

第二种方法是允许您部署的远程服务器访问GitHub - 这可能是弹性beanstalk或您的实际服务器。在服务器上创建无密码ssh密钥(ssh-keygen -t rsa,接受默认值,或EB可能有自己的方法)然后复制生成的公钥内容并在GitHub仓库中创建一个包含该密钥的新“部署密钥” - 你需要成为管理员,我认为你是。已安装的部署密钥将允许EB用户登录远程服务器并从服务器执行git pull和相关命令(只读)。

我认为随着您部署的服务器数量的增加,第一种方法更优雅,更易于管理,但您使用的方法可能取决于EB的选项。

答案 4 :(得分:0)

从您的requirements.txt文件中删除私有github仓库,并创建脚本以使用环境变量(用于用户名和密码)安装它们。

文件: project-root / install-extra-requirements.sh

#!/bin/sh

source /opt/python/run/venv/bin/activate
python ".extra-requirements.py"

文件: project-root / .extra-requirements.py

import os

def main():
    github_username = os.environ['GITHUB_USERNAME']
    github_password = os.environ['GITHUB_PASSWORD']
    repository = "git+https://%s:%s@github.com/yourgithubrepo" % (github_username, github_password)
    os.system("pip install %s" % repository)

if __name__ == '__main__':
    main()

文件:project-root / .ebextensions / 002_container.config

container_commands:
  01_install_extra_requirements:
    command: './install-extra-requirements.sh'

现在,您只需在弹性beantalk环境中将GITHUB_USERNAME和GITHUB_PASSWORD设置为环境变量即可。