# 使用AWS CodePipeline 以及相关服务自动部署个人静态网站

首先创建S3存储桶,使用S3存储个人网站静态页面。然后开启S3的静态网站托管。可以通过终端节点 url,访问我们的个人静态网站。

每次手动将静态资源同步到S3,效率低下。所以可以结合 AWS CI/CD工具,实现自动化部署。

具体实现思路是,我们可以使用Git和AWS CodeCommit代码仓库,进行源代码管理。每次我们推送代码时,CodePipeline会监听更新,监听到更新,CodeBuild 会基于buildspec.yml构建脚本。执行构建,将静态资源同步到S3。这样便实现了个人静态网站自动部署。

通过S3的静态网站托管。生成的终端节点 url,是非常长,不利于访问,记忆的。因此,我们可以使用Route 53实现自定义域名。

进一步优化,我们可以通过AWS CloudFront分发个人静态网站。这将使我们的个人静态网站具有 SSl 证书,并且可以使用 Gzip 之类的工具压缩文件。并且 CloudFront 将使用 CDN 加速用户访问。

  • 使用S3存储个人网站静态页面
  • 使用Git和AWS CodeCommit代码仓库,进行源代码管理
  • 使用AWS CodePipeline自动部署个人静态网站
  • 使用S3的静态网站托管和无服务器访问日志
  • 使用Route 53实现自定义域名
  • 通过AWS CloudFront分发个人静态网站
  • 更新Route 53配置以使用CloudFront分配
  • 使用CodeBuild每次部署时,自动使CloudFront缓存无效

# 项目目录

项目目录结构如下:

├── dist #vuepress 项目,打包后的静态资源目录
├── docs #vuepress 项目目录
├── .gitignore
├── buildspec.yml #CodeBuild 构建脚本文件
├── package.json
└── node_modules

buildspec.yml

version: 0.2

phases: 
  pre_build:
    commands:
      # 打印开始部署时的时间
      - echo 开始部署 `date`
      - echo Syncing S3 Content
      # 将dist目录下的文件,同步到指定的S3存储桶
      # 将yourwebsite.com 替换为存放您的应用静态网站的S3存储桶的名称
      - aws s3 sync ./dist/ s3://yourwebsite.com
  build:
    commands:
      - echo 使CloudFront缓存无效
      # 在文件过期前从 CloudFront 边缘缓存中删除文件,每次构建时清除缓存
      # 将CloudFront服务创建的,CloudFront分配的ID属性替换XXXXXXXX
    #   - aws cloudfront create-invalidation --distribution-id XXXXXXXX --paths "/*"
  post_build:
    commands:
      # 打印部署结束时的时间
      - echo 部署完成于 `date`

# 使用S3存储个人网站静态页面

# 创建S3存储桶

  • 转到 Amazon S3 服务控制台,创建一个S3存储桶。
  • 点击 创建存储桶 按钮,输入存储桶名称,选择区域,取消 阻止所有公有访问权限 勾选,点击创建存储桶。
  • 选择刚才创建的存储桶,进入编辑页面。更新存储桶 IAM 策略。点击 权限,点击 存储桶策略。我们可以在此处输入策略。但是最好点击 策略生成器。跳转到 策略生成器页面。生成策略。
  • 策略类型选择,S3 Bucket Policy。Principal,设置为 * 通配符,允许每个人都能访问这个存储桶。Actions,设置为 GetObject,Amazon Resource Name (ARN),设置为,上一步 存储桶策略 页面的存储桶ARN,并在路径后面加上 /*,这样就可以访问存储桶中的所有对象。点击 Add Statement,点击 Generate Policy,将弹窗内的策略文档拷贝到上一步 存储桶策略,的文本编辑框中。点击保存。现在页面显示 此存储桶拥有公共访问权限

# 使用Git和AWS CodeCommit代码仓库,进行源代码管理

在 CodeCommit 设置 Git 仓库,并设置 CI/CD 流水线。使构建过程自动化,每当我们将代码推送到 CodeCommit时,将自动更新S3存储桶,从而更新我们的个人静态网站。

# 创建存储库

  • 转到 Amazon CodeCommit 服务控制台,创建一个存储库。
  • 点击 创建存储库 按钮,输入存储库名称,点击 创建。存储库创建完成。

要从计算机连接到这个存储库,我们应该使用 IAM 创建一个用户。

# 使用 IAM 创建合法用户

  • 转到 Amazon IAM 服务控制台,点击左侧 用户 栏。跳转到创建用户页面。
  • 点击 添加用户,输入用户名 git-service-test,访问类型,设置为 编程访问,点击下一步。
  • 直接附加现有策略,选择 AWSCodeCommitFullAccess。点击下一步。点击下一步。点击 创建用户。用户成功创建。
  • 转到用户界面,选择刚才的用户,进入用户编辑页面。点击 安全证书针对 AWS CodeCommit 的 HTTPS Git 凭证,点击 生成凭证 按钮。在弹窗页面下载证书,并复制用户名,密码。用于git提交代码是,身份验证。
  • 转到 Amazon CodeCommit 服务控制台,创建一个存储库。选择刚才创建的存储库,进入编辑页面,点击 克隆URL 按钮,复制远程仓库地址。
  • 转到 VS Code 控制台,将 CodeCommit 存储库添加为远程仓库 git remote add origin 存储库地址
  • 当使用 git push 推送代码时,会提示需要填写上面生成的用户名,和密码。下次提交时不需要输入。
  • 转到 CodeCommit 存储库,会看到文件已经上传到改存储库。

# 使用AWS CodePipeline自动部署个人静态网站

设置 CI/CD 流水线,自动部署应用程序。

  • 转到 Amazon CodePipeline 服务控制台,点击 创建流水线 栏。
  • 输入流水线名称,点击 高级设置。构件存储,选择自定义位置,在下拉列表中选择我们上面S3创建的存储桶。点击下一步。
  • 源提供程序,选择 AWS CodeCommit。存储库名称,选择上面CodeCommit创建的存储库。分支选择master。点击下一步。
  • 构建提供程序,选择 AWS CodeBuild。项目名称,点击创建项目。调整到创建项目页面。
  • 设置项目名称。环境映像,设置托管映像。操作系统选择Ubuntu。运行时选择,Standard。映像选择,aws/codebuild/standard:4.0,点击 前往 CodePipeline,成功创建项目。
  • 项目名称,指定为上面创建的项目。点击下一步。
  • 添加部署阶段,不需要部署提供程序,直接点击 跳过部署阶段。然后点击创建流水线。流水线创建成功,开始执行构建。dist 目录下的静态资源,同步到指定的S3存储桶

# 使用S3的静态网站托管和无服务器访问日志

将S3配置为托管个人网站的静态网站。

  • 转到 Amazon S3 服务控制台,选择我们上面创建的存储桶。进入编辑页面。
  • 点击 属性,点击 静态网站托管,选择 使用此存储桶托管网站,索引文档设置为index.html,错误文档设置为vuepress打包生成的 404.html。点击保存 。静态网站托管,处于激活状态。点击终端节点,可以访问个人静态网站。
  • 转到 Amazon S3 服务控制台,创建一个日志访问的存储桶。
  • 回到托管个人静态网站的存储桶,点击 属性,点击 服务器访问日志记录,点击 启用日志记录,选择上面的日志存储桶。可以设置 目标前缀,那么访问日志将存储在目标前缀对应的目录中,点击保存。然后日志存储桶就能看到访问日志了。

# 使用Route 53实现自定义域名

基于我们已经注册了域名。

使用Route 53将我们的自定义域名,执行个人静态网站对应的S3存储桶。

  • 转到 Amazon Route 53 服务控制台,点击托管区域,跳转到托管区域列表页面,选择我们指定的域名。
  • 我们只需要添加一个指向S3存储桶的 A记录,即可。
  • 点击 创建记录集 按钮,名称设置为空,以使用根域。类型是 A。
  • 开启别名,别名目标,选择我们上面创建的S3存储桶。点击创建。
  • 解析url需要一段时间,解析完成后就能使用自定义域名访问我们的个人静态网站了。

# 使用ACM将SSL证书添加到自定义域

  • 转到 Amazon ACM 服务控制台,特别需要注意,我们必须将区域设置为 美国东部 (弗吉尼亚北部)或 us-east-1。因为,那是边缘位置所在地,大多数服务,例如 CloudFront,要求正式安装在此地。
  • 选择区域后,点击 预置证书,开始使用。
  • 选择 请求公有证书,点击 请求证书
  • 添加域名,将域名设置为 serverless-action,向此证书添加另一个名称,设置为 *.serverless-action。这将添加一个通配符证书,我们可以在该域名的子域上使用它。点击下一步。
  • 选择验证方法,选择 DNS 验证,点击下一步。
  • 添加标签,点击审核。
  • 审核并请求,点击确认并请求。
  • 验证,正在审核中,展开域,我们必须在DNS记录中添加这些记录以进行所有权验证。在我们的例子中,DNS提供程序是Route 53,点击展开的域中,对应的按钮,即可为我们自动创建必要的DNS记录。转到Route 53,在CNAME条目中,会找到相关的记录。
  • 点击继续,几分钟后我们应该有一个激活的SSL证书。证书颁发需要一定时间。

# 通过AWS CloudFront分发个人静态网站

假设我们的自定义域名为 serverless-action,如果想通过 www.serverless-action 子域名访问个人静态网站,可以通过创建另一个存储桶,像上面一样设置静态网站托管,但是选择 重定向请求,而不是 使用此存储桶托管网站。并且将目标存储桶指向 serverless-action 对应的存储桶。并在Route 53创建一个新的记录集,指向 www.serverless-action 对应的存储桶。

我们不会这样做,我们将设置 CloudFront 分发我们的个人静态网站。然后将自定义域名指向 CloudFront,而不是指向S3存储桶。

这将使我们的个人静态网站具有 SSl 证书,并且可以使用 Gzip 之类的工具压缩文件。并且 CloudFront 将使用 CDN 加速用户访问。

  • 转到 Amazon CloudFront 服务控制台。
  • 点击 创建分配,内容分发方式,选择 Web,点击 入门
  • 源域名,选择托管个人静态网站的S3存储桶,开启 自动压缩对象。价格级别,选择 使用所有边缘站点 (最佳性能)。备用域名,可以填写一个域或其子域名。SSL 证书,选择 自定义 SSL 证书,设置为我们上面使用ACM创建的证书。默认根对象,设置为 index.html。这是个人静态网站的入口文件。开启日志记录,并选择之前用S3创建的日志存储桶。可以设置 日志前缀,区分来自 CloudFront 的日志。点击 创建分配
  • 需要一些时间完成 CloudFront 分配 的部署。

# 更新Route 53配置以使用CloudFront分配

CloudFront 分配 已经部署完成,现在将Route 53使用该分配作为目标。

  • 转到 Amazon Route 53 服务控制台,点击托管区域,跳转到托管区域列表页面,选择我们指定的域名。
  • 修改指向S3存储桶的A记录,开启别名,别名目标,选择我们上面创建的 CloudFront 分配
  • www.serverless-action子域创建一个记录集,名称设置为wwww,类型是 A。开启别名,别名目标,选择我们上面创建的 CloudFront 分配
  • 现在可以从serverless-action和子域www.serverless-action 访问我们的个人静态网站了。

# 使用CodeBuild每次部署时,自动使CloudFront缓存无效

buildspec.yml 构建脚本文件

开启aws cloudfront create-invalidation。CodeBuild每次部署时,自动使CloudFront缓存无效。

version: 0.2

phases: 
  pre_build:
    commands:
      # 打印开始部署时的时间
      - echo 开始部署 `date`
      - echo Syncing S3 Content
      # 将dist目录下的文件,同步到指定的S3存储桶
      # 将yourwebsite.com 替换为存放您的应用静态网站的S3存储桶的名称
      - aws s3 sync ./dist/ s3://yourwebsite.com
  build:
    commands:
      - echo 使CloudFront缓存无效
      # 在文件过期前从 CloudFront 边缘缓存中删除文件,每次构建时清除缓存
      # 将CloudFront服务创建的,CloudFront分配的ID属性替换XXXXXXXX
      - aws cloudfront create-invalidation --distribution-id XXXXXXXX --paths "/*"
  post_build:
    commands:
      # 打印部署结束时的时间
      - echo 部署完成于 `date`
  • 转到 Amazon CloudFront 服务控制台,将CloudFront服务创建的,指定的CloudFront分配的ID属性替换XXXXXXXX。
  • 将代码推送到 CodeCommit 指定分支,CodePipeline会调用 CodeBuild服务部署个人静态网站,在 build 阶段,执行aws cloudfront create-invalidation 指令使CloudFront缓存无效。

# 上线问题解决

# 为什么 CloudFront 不返回子目录中的默认根对象?

CloudFront 的默认根对象功能仅支持您的分配指向的源的根。CloudFront 不返回子目录中的默认根对象。

导致我们访问子目录时,不会定向到子目录下的 index.html,导致返回 404错误

解决方法:修改CloudFront 分配,选择对应的分配对象,编辑源,将 源域名 设置为,托管个人静态网站的S3存储桶的 终端节点 url。不要设置为托管个人静态网站的S3存储桶。

更多解决方案

更新时间: 5/16/2020, 2:31:12 PM