var*_*yar 11 git github git-submodules aws-code-deploy
我的git存储库中有一个子模块,我的目录结构是这样的,
app
-- folder1
-- folder2
-- submodule @5855
Run Code Online (Sandbox Code Playgroud)
我已使用autodeploy服务在AWS上部署了我的代码.现在,在服务器上,我在父目录中有代码,但子模块目录是空的.
Q1)如何在子模块中获取数据.我在服务器上的存储库不是git存储库.我是否需要先将其转换为git repo,然后运行submodule命令才能获得它?
Q2)如何自动化子模块部署?
谢谢
Mat*_*cci 11
我明天会清理这个答案,但这对我有用
我们将重新初始化git存储库,然后在部署的构建阶段触发子模块克隆,基本上修补了对codepipeline/codebuild中的子模块的支持
aws ssm put-parameter --name build_ssh_key --type String --value "$(cat id_rsa)"使用SecureString而不是String 将这个ssh密钥存储在你的aws参数存储中,但是我之后的指南只是使用了字符串,所以我不确定命令行是否需要任何额外的参数,明天将测试然后使您的buildspec.yml看起来如下所示:
version: 0.2
env:
parameter-store:
build_ssh_key: "build_ssh_key"
phases:
install:
commands:
- mkdir -p ~/.ssh
- echo "$build_ssh_key" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keygen -F github.com || ssh-keyscan github.com >>~/.ssh/known_hosts
- git config --global url."git@github.com:".insteadOf "https://github.com/"
- git init
- git remote add origin <Your Repo url here using the git protocol>
- git fetch
- git checkout -t origin/master
- git submodule init
- git submodule update --recursive
build:
commands:
- echo '...replace with real build commands...'
artifacts:
files:
- '**/*'
Run Code Online (Sandbox Code Playgroud)
经过一整天的努力,我找到了一个简单的解决方案(用于代码管道),它不需要在 buildspec 中处理任何 SSH 密钥。我正在使用 Bitbucket,但我认为这适用于其他提供商。我也在通过 https 克隆我的子模块,我不确定这是否是一个要求。
配置您的构建角色以添加客户管理的 UseConnection 权限,以授予您的构建操作访问您为源配置的凭据的权限。来自 AWS 的文档:https : //docs.aws.amazon.com/codepipeline/latest/userguide/troubleshooting.html#codebuild-role-connections
设置您的 env 以包含git-credential-helper: yes并在 buildspec.yml 中克隆子模块:
就是这样!子模块将可用于构建,而无需为您要使用的每个子模块进行大量关键配置。
如果这最终对人们有用,也许是对文档的一个很好的补充。
我自己遇到了这个问题,并且由于@ matt-bucci的出色建议,我得以提出一个看似健壮的解决方案。
我的特定用例略有不同-我使用Lambda层来减少lambda冗余,但仍需要将这些层作为子模块包含在Lambda函数存储库中,以便CodeBuild可以构建和测试PR。我还使用CodePipeline来协助持续交付-因此我需要一个本身可以同时使用CodePipeline和CodeBuild的系统
按照这些说明,我创建了一个新的SSH密钥,供“机器用户” 使用。在这种情况下,我使用的是计算机用户,因此不需要为每个项目都生成新的ssh密钥,也不需要为多个私有子模块提供潜在的支持
我将私钥作为SecureString存储在AWS Parameter Store中。这实际上并没有改变CodeBuild中的任何内容,因为它足够聪明,只知道如何解密密钥
我给了“ codebuild”角色AWS托管属性:AmazonSSMReadOnlyAccess-允许CodeBuild访问私钥
我使用@ matt-bucci建议的一堆命令以及一些新命令创建了buildspec.yml文件。
# This example buildspec will enable submodules for CodeBuild projects that are both
# triggered directly and via CodePipeline
#
# This buildspec is designed with help from Stack Overflow:
# /sf/ask/2989877971/
version: 0.2 # Always use version 2
env:
variables:
# The remote origin that will be used if building through CodePipeline
remote_origin: "git@github.com:your/gitUri"
parameter-store:
# The SSH RSA Key used by our machine user
ssh_key: "ssh_key_name_goes_here"
phases:
install:
commands:
# Add the "machine user's" ssh key and activate it - this allows us to get private (sub) repositories
- mkdir -p ~/.ssh # Ensure the .ssh directory exists
- echo "$ssh_key" > ~/.ssh/ssh_key # Save the machine user's private key
- chmod 600 ~/.ssh/ssh_key # Adjust the private key permissions (avoids a critical error)
- eval "$(ssh-agent -s)" # Initialize the ssh agent
- ssh-add ~/.ssh/ssh_key # Add the machine user's key to the ssh "keychain"
# SSH Credentials have been set up. Check for a .git directory to determine if we need to set up our git package
- |
if [ ! -d ".git" ]; then
git init # Initialize Git
git remote add origin "$remote_origin" # Add the remote origin so we can fetch
git fetch # Get all the things
git checkout -f "$CODEBUILD_RESOLVED_SOURCE_VERSION" # Checkout the specific commit we are building
fi
# Now that setup is complete, get submodules
- git submodule init
- git submodule update --recursive
# Additional install steps... (npm install, etc)
build:
commands:
# Build commands...
artifacts:
files:
# Artifact Definitions...
Run Code Online (Sandbox Code Playgroud)
该安装脚本执行三个独立的步骤
它安装并启用用于访问私有存储库的ssh私有密钥
它确定是否存在.git文件夹-如果没有,则脚本将初始化git并检出正在构建的确切提交。注意:根据AWS文档,$CODEBUILD_RESOLVED_SOURCE_VERSIONenvar不保证存在于CodePipeline构建中。但是,我没有看到这个失败
最后,它实际上获得了子模块
显然,这不是解决此问题的好方法。但是,鉴于CodePipeline的(不必要)限制,这是我能想到的最好的方法。此过程的副作用是“源” CodePipeline阶段是完全不值钱的,因为我们只是覆盖已归档的源文件-它仅用于侦听存储库的更改
两年来,人们一直要求更好的功能:https : //forums.aws.amazon.com/thread.jspa?threadID=248267
我意识到(艰难的方式)我以前的响应不支持CodePipeline构建,仅直接通过CodeBuild运行。当CodeBuild响应GitHub Webhook时,它将克隆整个GitHub存储库,包括.git文件夹
但是,当使用CodePipeline时,“源”操作将克隆存储库,签出相应的分支,然后在不带 .git文件夹的情况下处理原始文件。这意味着我们必须初始化github存储库才能访问子模块
我在AWS CodeBuild上遇到了同样的问题。我Use Git submodules像下图一样勾选以更新我的submodule.
当我运行构建时出现以下错误,
CLIENT_ERROR: Submodule error error creating SSH agent: "SSH agent requested but SSH_AUTH_SOCK not-specified" for primary source and source version refs/heads/dev
Run Code Online (Sandbox Code Playgroud)
因此,我在 google 上搜索了上述错误,并从 AWS 论坛得到了DOWNLOAD_SOURCE Fails with Git submodules线程。他们提到过,
子模块必须配置为 https 而不是 ssh。
我认为这没什么用,有人设置submodule为会发生什么ssh。我也做了同样的事情,这是我的.gitmodules文件。
[submodule "common"]
path = common
url = git@bitbucket.org:organization_id/common.git
Run Code Online (Sandbox Code Playgroud)
真的,我不想把它改成https。然后我在媒体上找到了这篇Working with Git Submodules in CodePipeline文章。我想想象一下我为解决此问题所做的工作,并且存在该文章中未提及的错误。让我们以更安全的方式做到这一点。
首先转到AWS Key Management Service (KMS),然后转到Customer managed keys部分并单击Create key创建密钥。
Symmetric,然后单击Next。bitbucket-credentials)来创建Alias并单击Next。AWS Role配置任何开发人员工具,因此在我的例子中,我创建了对AWS CodeBuild 的调用,并为其提供了 并单击。AWS RoleecsCodeBuildRoleDefine key administrative permissionsNextDefine key usage permissions您的AWS Role并单击Next。Finish以创建CMK。AWS Key Management Service (KMS)部分已完成,现在转到AWS Systems Manager并找到该Parameter Store部分。点击Create parameter。
id_rsa并放置与下面相同的内容即可。value部分,只需cat ~/.ssh/id_rsa在终端中运行命令,您将获得如下所示的输出。将其添加到该value部分。-----BEGIN RSA PRIVATE KEY-----
qdjbXp+42VTnccC7pxOZcofomfwGXPWuqcv99sQEPtToODvGIxWoooJUpb6qMIWY
1zccEuwAhmqcPvpsJyWhcctZB/wWglNvViZcOYjrQ8HBUBKJT8pF
-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
创建另一个参数并将其命名为id_rsa.pub。按照与上面相同的步骤进行操作。
对于本value部分,只需cat ~/.ssh/id_rsa.pub在终端中运行命令,您将获得如下所示的输出。将其添加到该value部分。
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGtf8jjkogWxRGNGjJlOZ1G+pWExgDOdA5wVML6TMTT2YtvhPJD60nPx5TfA8zRzGWubwrPp40SPAhSs5wiAAg38HlS4pz9X wasdkiller@wasdkiller
Run Code Online (Sandbox Code Playgroud)
根据我的研究(也许我错了,请纠正我),我没有任何其他方法可以在不付出这么多努力的情况下将ssh凭证传递给AWS CodeBuild 。所以我buildspec.yml像这样手动更改了我的文件。
version: 0.2
env:
parameter-store:
ssh_key: id_rsa
ssh_pub: id_rsa.pub
phases:
install:
commands:
- mkdir -p ~/.ssh
- echo "$ssh_key" > ~/.ssh/id_rsa
- echo "$ssh_pub" > ~/.ssh/id_rsa.pub
- chmod 600 ~/.ssh/id_rsa
- eval "$(ssh-agent -s)"
- git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)
当你继续时,你肯定会得到以下错误,
version: 0.2
env:
parameter-store:
ssh_key: id_rsa
ssh_pub: id_rsa.pub
phases:
install:
commands:
- mkdir -p ~/.ssh
- echo "$ssh_key" > ~/.ssh/id_rsa
- echo "$ssh_pub" > ~/.ssh/id_rsa.pub
- chmod 600 ~/.ssh/id_rsa
- eval "$(ssh-agent -s)"
- git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)
它会询问您的ssm:GetParameters权限,只需附加AmazonSSMReadOnlyAccess策略或使用权限手动创建策略ssm:GetParameters并将其附加到您的AWS Role,它就会解决这个问题。
虽然@MattBucci 的回答有效,但需要注意的是,您只能拉取特定分支,而不能拉取子模块正在使用的特定提交。
为了处理这种情况,这在使用子模块时很可能发生,需要做很多事情:
1)创建一个gitpre-commit钩子,内容如下:
#!/bin/bash
# This file is used in post-commit hook
# if .commit exists you know a commit has just taken place but a post-commit hasn't run yet
#
touch .commit
Run Code Online (Sandbox Code Playgroud)
如果您已经有了,可以在开头添加该行。
2)post-commit使用以下内容创建一个 git钩子:
#!/bin/bash
DIR=$(git rev-parse --show-toplevel);
if [[ -e $DIR/.commit ]]; then
echo "Generating submodule integrity file"
rm .commit
SUBMODULE_TRACKING_FILE=$DIR/.submodule-hash
MODULE_DIR=module
# Get submodule hash, this will be used by AWS Code Build to pull the correct version.
# AWS Code Build does not support git submodules at the moment
# https://forums.aws.amazon.com/thread.jspa?messageID=764680#764680
git ls-tree $(git symbolic-ref --short HEAD) $MODULE_DIR/ | awk '{ print $3 }' > $SUBMODULE_TRACKING_FILE
git add $SUBMODULE_TRACKING_FILE
git commit --amend -C HEAD --no-verify
fi
exit 0
Run Code Online (Sandbox Code Playgroud)
这个钩子会将当前提交的哈希放入.submodule-hash文件中,这个文件需要提交给版本控制。
3)转到您的 AWS 代码构建项目
Developer Tools > CodeBuild > Build projects > YOUR_PROJECT > Edit Environment
Run Code Online (Sandbox Code Playgroud)
添加一个名为: 的环境变量GIT_KEY,该值将是 64 位编码的 ssh 密钥。(没有换行符,否则将无法工作)。
您可以在线转换它,或使用任何工具或编程语言。
4)在你buildspec.yml添加一个pre_build脚本。
version: 0.2
phases:
pre_build:
commands:
- bash build/aws-pre-build.sh
...
Run Code Online (Sandbox Code Playgroud)
5)build/aws-pre-build.sh使用以下内容创建:
Developer Tools > CodeBuild > Build projects > YOUR_PROJECT > Edit Environment
Run Code Online (Sandbox Code Playgroud)
如果在转到 AWS 代码构建之前有一个额外的步骤,例如 bitbucket 管道或类似的东西,您可以检查实际的 git 子模块哈希是否与生成的文件中的哈希匹配:.submodule-hash.
如果它不匹配,则意味着曾经推送过的人没有 git 钩子。
version: 0.2
phases:
pre_build:
commands:
- bash build/aws-pre-build.sh
...
Run Code Online (Sandbox Code Playgroud)
注意:您还可以在 AWS Code Build 之前在管道上创建该文件、创建提交、标记并推送它,以便 AWS Code Build 管道开始。
#!/bin/bash
set -e
# Get root path
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
MODULE_HASH=$(cat $DIR/.submodule-hash);
GIT_HOST=bitbucket.org
MODULE_DIR=module
REPO=user/repo.git
if [[ ! -d ~/.ssh ]]; then
mkdir ~/.ssh
fi
if [[ ! -f ~/.ssh/known_hosts ]]; then
touch ~/.ssh/known_hosts
fi
# Base64 decode private key, and save it to ~/.ssh/git
echo "- Adding git private key"
echo $GIT_KEY | base64 -d > ~/.ssh/git
# Add correct permissions to key
chmod 600 ~/.ssh/git
# Add $GIT_HOST to ssh config
echo "- Adding ssh config file"
cat > ~/.ssh/config <<_EOF_
Host $GIT_HOST
User git
IdentityFile ~/.ssh/git
IdentitiesOnly yes
_EOF_
# Check if host is present in known_hosts
echo "- Checking $GIT_HOST in known_hosts"
if ! ssh-keygen -F $GIT_HOST > /dev/null; then
echo "- Adding $GIT_HOST to known hosts"
ssh-keyscan -t rsa $GIT_HOST >> ~/.ssh/known_hosts
fi
# AWS Code build does not send submodules, remove the empty folder
rm -rf $MODULE_DIR
# Clone submodule in the right folder
git clone git@$GIT_HOST:$REPO $MODULE_DIR
# cd to submodule
cd $DIR/$MODULE_DIR
# Checkout the right commit
echo "- Checking out $MODULE_HASH"
git checkout $MODULE_HASH
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2859 次 |
| 最近记录: |