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_VERSION
envar不保证存在于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 Role
ecsCodeBuildRole
Define key administrative permissions
Next
Define 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)