有没有可能在AppSpec文件的section文件中使用CodeDeploy环境变量?

12

我有一个网站,存储在AWS EC2服务器上。

我们有两个服务器,一个用于生产环境,另一个用于开发和测试环境。

开发和测试环境位于不同的文件夹中。例如,开发环境存储在/var/www/development,而测试环境存储在/var/www/staging

我想使用AWS CodeDeploy直接从Bitbucket上传文件。我放置了AppSpec文件,将源代码复制到/var/www/html文件夹,并安装所有依赖项和配置。但是我希望我的AppSpec文件根据选择的开发组,将源代码复制到/var/www/development/var/www/staging

是否有任何方法可以做到这一点,或者在我这种情况下有更好的方法?


为两个实例添加标签,例如:生产服务器将具有标签 env:prod,而暂存服务器将具有 env:stage。在您的 appspec 钩子中,首先获取此标签,然后决定将归档文件复制到哪里。 - Ravi
@levchuk-ivan,你最终解决了这个问题吗?我现在也遇到了类似的情况。谢谢。 - flopperJ
@flopperJ,是的,但我不喜欢这个解决方案。默认情况下,应用程序发布副本到一个文件夹中,部署脚本会将源代码移动到与部署组名称相对应的文件夹中。 - Liauchuk Ivan
3个回答

7
appspec.yml 有一些局限性,因此使用以下方法将代码部署到同一实例上的不同文件夹中。
version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/my-temp-dir
permissions:
  - object: /var/www/my-temp-dir
    owner: ec2-user
    group: ec2-user
hooks:
  BeforeInstall:
    - location: ci/integrations-deploy-pre.sh
      runas: root
  AfterInstall:
    - location: ci/integrations-deploy-post.sh
      runas: root

在我的integrations-deploy-post.sh文件中,我使用CodeDeploy环境变量将文件移动到需要的位置。

#!/bin/bash
    
if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ]
then
    cp -R /var/www/my-temp-dir /var/www/my-staging-dir
    chown -R ec2-user:ec2-user /var/www/my-staging-dir

    # Insert other commands that need to run...
fi

if [ "$DEPLOYMENT_GROUP_NAME" == "UAT" ]
then
    cp -R /var/www/my-temp-dir /var/www/my-uat-dir
    chown -R ec2-user:ec2-user /var/www/my-uat-dir

    # Insert other commands that need to run...
fi

注意:在我的integrations-deploy-post.sh文件中,你还需要添加你想要在生产环境上运行的命令。为了简化,本文不包含这些内容。


4
推荐更改AppSpec或自定义脚本行为的方法是利用CodeDeploy代理提供的环境变量。您可以访问部署组名称和应用程序名称。
if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ]; then
  # Copy to /var/www/staging
elif [ "$DEPLOYMENT_GROUP_NAME" == "Development" ]; then
  # Copy to /var/www/development
elif [ "$DEPLOYMENT_GROUP_NAME" == "Production" ]; then
  # Copy to /var/www/html
else
  # Fail the deployment
fi

1
那么我不能使用appspec文件的files部分,我应该自己复制所有文件吗? - Liauchuk Ivan
嗨 @EmptyArsenal,想法是对的,但语法有误。应该使用fi而不是end。 - Harsh Patel

0
我曾遇到同样的问题,但我使用源代码控制作为解决方案。我的工作流程是使用Gitlab CI > AWS Code Pipeline(S3源和CodeDeploy)。
因此,在我的开发分支中,我的AppSpec文件会像这样:-
version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/my-project-dev
hooks:
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 400
      runas: root

在我的暂存分支中:

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/my-project-staging
hooks:
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 400
      runas: root

我的Gitlab-CI只是使用shell执行器连接到我的EC2实例,它基本上压缩我的项目文件夹并上传到S3。

.gitlab-ci.yml

stages:
  - deploy
setup dependencies:
  stage: .pre
  script:
    - echo "Setup Dependencies"
    - pip install awscli
deploy to s3:
  stage: deploy
  script:
    - tar -cvzf /tmp/artifact_$CI_COMMIT_REF_NAME.tar ./*
    - echo "Copy artifact to S3"
    - aws s3 cp /tmp/artifact_$CI_COMMIT_REF_NAME.tar s3://project-artifacts/

clean up:
  stage: .post
  script:
    - echo "Removing generated artifact"
    - rm /tmp/artifact_$CI_COMMIT_REF_NAME.tar


请注意,$CI_COMMIT_REF_NAME 用于区分正在生成的工件文件。在开发分支中,它将是 artifact_development.tar,在暂存分支中则为 artifact_staging.tar
然后,我有两个管道分别监听这两个工件,它们部署到两个不同的 CodeDeploy 应用程序。
不确定这是否是最好的方法,欢迎任何更好的建议。

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