{"id":48524,"date":"2023-05-12T17:44:21","date_gmt":"2024-01-11T16:34:47","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/"},"modified":"2024-04-30T03:49:59","modified_gmt":"2024-04-29T19:49:59","slug":"%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/","title":{"rendered":"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb"},"content":{"rendered":"<h1>\u6211\u60f3\u505a\u7684\u4e8b\u60c5<\/h1>\n<p>\u6211\u5728\u4f7f\u7528GitHub Actions\u4e2d\u7684Terragrunt\u65f6\uff0c\u6b63\u5728\u7814\u7a76\u5982\u4f55\u5728pull request\u4e2d\u8bc4\u8bbaplan\u7ed3\u679c\u3002<br \/>\n\u867d\u7136\u6211\u80fd\u591f\u76f4\u63a5\u8bc4\u8bbaplan\u7ed3\u679c\uff0c\u4f46\u6211\u60f3\u77e5\u9053\u662f\u5426\u6709\u66f4\u597d\u7684\u65b9\u6cd5\uff0c\u6240\u4ee5\u6211\u51b3\u5b9a\u5c1d\u8bd5\u4e0etfcmt\u7ed3\u5408\u4f7f\u7528\u3002<\/p>\n<h1>Terragrunt\u662f\u4ec0\u4e48\uff1f<\/h1>\n<p>Terragrunt\u662f\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u7684\u5c01\u88c5\u5de5\u5177\uff0c\u5b83\u4f7f\u5f97Terraform\u66f4\u52a0\u65b9\u4fbf\u3002<br \/>\n\u5b83\u80fd\u591f\u5c06\u8bbe\u7f6e\u4fdd\u6301DRY\uff0c\u5e76\u4e14\u4f7f\u5f97\u7ba1\u7406\u591a\u4e2aTerraform\u6a21\u5757\u548c\u8fdc\u7a0b\u72b6\u6001\u53d8\u5f97\u66f4\u52a0\u5bb9\u6613\u3002<\/p>\n<p>\u5982\u679cTerraform\u7684\u72b6\u6001\u88ab\u5206\u4e3a\u591a\u4e2a\u76ee\u5f55\uff0c\u5e76\u4e14\u5b58\u5728\u4f9d\u8d56\u5173\u7cfb\uff0c\u6211\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u5b9e\u7528\u7684\u5de5\u5177\u3002<br \/>\n\u7531\u4e8e\u5b83\u62e5\u6709\u8bb8\u591a\u4fbf\u5229\u529f\u80fd\uff0c\u6240\u4ee5\u6211\u60f3\u5982\u679c\u60a8\u8fd8\u6ca1\u6709\u4f7f\u7528\u8fc7\u5b83\uff0c\u4e00\u5b9a\u8981\u5c1d\u8bd5\u4e00\u6b21\u3002<\/p>\n<p>&nbsp;<\/p>\n<h1>Tfcmt\u662f\u4ec0\u4e48\uff1f<\/h1>\n<blockquote><p>tfcmt \u662f\u4e00\u4e2aCLI\u5de5\u5177\uff0c\u5c06terraform plan\u548capply\u7684\u7ed3\u679c\u4f5c\u4e3a\u8bc4\u8bba\u901a\u77e5\u5230GitHub\u7684Pull Request\uff08\u4ee5\u4e0b\u7b80\u79f0PR\uff09\u4e2d\u3002<br \/>\n\u4f7f\u7528\u8be5\u5de5\u5177\u53ef\u4ee5\u5728PR\u9875\u9762\u4e0a\u76f4\u63a5\u67e5\u770b\u7ed3\u679c\uff0c\u65e0\u9700\u67e5\u770bCI\u65e5\u5fd7\u3002<br \/>\n\u800c\u4e14\u76f8\u8f83\u4e8e\u539f\u59cb\u65e5\u5fd7\uff0c\u7ed3\u679c\u66f4\u52a0\u6e05\u6670\u6613\u61c2\u7684\u7279\u70b9\u3002<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h1>\u5982\u4f55\u4f7f\u7528tfcmt<\/h1>\n<p>\u4f7f\u7528\u4ee5\u4e0b\u65b9\u5f0f\u66ff\u6362terraform plan \u548cterraform apply.<\/p>\n<pre class=\"post-pre\"><code>$ tfcmt plan -- terraform plan [terraform plan \u306e\u5f15\u6570...]\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>$ tfcmt apply -- terraform apply [terraform apply \u306e\u5f15\u6570...]\r\n<\/code><\/pre>\n<p>\u5982\u679c\u5c06terraform\u547d\u4ee4\u76f4\u63a5\u66ff\u6362\u4e3aterragrunt\u547d\u4ee4\uff0c\u7531\u4e8e\u65e0\u6cd5\u4f7f\u7528run-all\u9009\u9879\uff0c\u56e0\u6b64\u9700\u8981\u7a0d\u52a0\u4fee\u6539\u3002<\/p>\n<h1>\u4f7f\u7528Terragrunt\u548ctfcmt\u7684\u7ec4\u5408\u65b9\u6cd5<\/h1>\n<p>\u5728terragrunt\u547d\u4ee4\u7684\u9009\u9879\u4e2d\u6307\u5b9a&#8211;terragrunt-tfpath\u3002\u901a\u8fc7\u8fd9\u4e2a\u9009\u9879\uff0c\u60a8\u53ef\u4ee5\u6307\u5b9a\u5728Terragrunt\u5185\u90e8\u6267\u884c\u7684terraform\u547d\u4ee4\u6240\u66ff\u4ee3\u7684\u53ef\u6267\u884c\u6587\u4ef6\u3002\u901a\u8fc7\u6307\u5b9a\u5230\u50cf\u4e0b\u9762\u7684shell\u811a\u672c\u7684\u8def\u5f84\uff0c\u60a8\u53ef\u4ee5\u81ea\u5b9a\u4e49terraform\u547d\u4ee4\u7684\u884c\u4e3a\u3002<\/p>\n<pre class=\"post-pre\"><code>terragrunt run-all plan --terragrunt-tfpath $GITHUB_WORKSPACE\/.github\/scripts\/tfwrapper.sh\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">#!\/bin\/bash<\/span>\r\n\r\n<span class=\"nb\">set<\/span> <span class=\"nt\">-euo<\/span> pipefail\r\n\r\n<span class=\"c\"># \u30b3\u30de\u30f3\u30c9\u306e\u7a2e\u985e\u3092\u53d6\u5f97(\u4f8b: apply, plan, fmt...)<\/span>\r\n<span class=\"nb\">type<\/span><span class=\"o\">=<\/span><span class=\"si\">$(<\/span><span class=\"nb\">echo<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$@<\/span><span class=\"s2\">\"<\/span> |  <span class=\"nb\">awk<\/span> <span class=\"s1\">'{print $1}'<\/span><span class=\"si\">)<\/span>\r\n\r\n<span class=\"c\"># \u5b9f\u884c\u3057\u3066\u3044\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u540d\u3092\u53d6\u5f97<\/span>\r\n<span class=\"nv\">current_dir<\/span><span class=\"o\">=<\/span><span class=\"si\">$(<\/span><span class=\"nb\">pwd<\/span> | <span class=\"nb\">sed<\/span> <span class=\"s1\">'s\/.*\\\/\/\/g'<\/span><span class=\"si\">)<\/span>\r\n\r\n<span class=\"k\">if<\/span> <span class=\"o\">[<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$type<\/span><span class=\"s2\">\"<\/span> <span class=\"o\">==<\/span> <span class=\"s2\">\"plan\"<\/span> <span class=\"o\">]<\/span><span class=\"p\">;<\/span> <span class=\"k\">then<\/span>\r\n    <span class=\"c\"># plan\u306e\u3068\u304d\u306f-patch\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4ed8\u3051\u308b<\/span>\r\n    <span class=\"c\"># \u5b9f\u884c\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u540d\u3092\u30bf\u30fc\u30b2\u30c3\u30c8\u3068\u3057\u3066\u6307\u5b9a<\/span>\r\n    tfcmt <span class=\"nt\">-var<\/span> <span class=\"s2\">\"target:<\/span><span class=\"k\">${<\/span><span class=\"nv\">current_dir<\/span><span class=\"k\">}<\/span><span class=\"s2\">\"<\/span> plan <span class=\"nt\">-patch<\/span> <span class=\"nt\">--<\/span> terraform <span class=\"s2\">\"<\/span><span class=\"nv\">$@<\/span><span class=\"s2\">\"<\/span>\r\n<span class=\"k\">elif<\/span> <span class=\"o\">[<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$type<\/span><span class=\"s2\">\"<\/span> <span class=\"o\">==<\/span> <span class=\"s2\">\"apply\"<\/span> <span class=\"o\">]<\/span><span class=\"p\">;<\/span> <span class=\"k\">then\r\n    <\/span>tfcmt <span class=\"nt\">-var<\/span> <span class=\"s2\">\"target:<\/span><span class=\"k\">${<\/span><span class=\"nv\">current_dir<\/span><span class=\"k\">}<\/span><span class=\"s2\">\"<\/span> apply <span class=\"nt\">--<\/span> terraform <span class=\"s2\">\"<\/span><span class=\"nv\">$@<\/span><span class=\"s2\">\"<\/span>\r\n<span class=\"k\">else\r\n    <\/span>terraform <span class=\"s2\">\"<\/span><span class=\"nv\">$@<\/span><span class=\"s2\">\"<\/span>\r\n<span class=\"k\">fi<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u6211\u4f1a\u6839\u636eterraform\u547d\u4ee4\u7684\u7c7b\u578b\u8fdb\u884c\u6761\u4ef6\u5206\u652f\u3002<br \/>\n\u5728\u6267\u884cplan\u548capply\u65f6\uff0c\u4f1a\u8fd0\u884ctfcmt\u547d\u4ee4\uff0c\u4f46\u662f\u5728\u6267\u884cplan\u65f6\u4f1a\u52a0\u4e0a-patch\u9009\u9879\u6765\u51cf\u5c11\u8bc4\u8bba\u7684\u6570\u91cf\u3002<br \/>\n\u5176\u4ed6\u547d\u4ee4\u5c06\u76f4\u63a5\u6267\u884c\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u53e6\u5916\uff0c\u5728tfcmt\u4e2d\uff0c\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528\u201c-var\u201d\u9009\u9879\u6765\u533a\u5206\u6bcf\u4e2a\u7ed3\u679c\uff0c\u4f8b\u5982\u201ctarget:foo\u201d\uff0c\u901a\u8fc7\u6807\u7b7e\u7684\u524d\u7f00\u6765\u533a\u5206\u3002\u6211\u4eec\u5229\u7528\u6b64\u529f\u80fd\u5c06\u6267\u884c\u76ee\u5f55\u540d\u79f0\u6307\u5b9a\u4e3a\u76ee\u6807\u3002<\/p>\n<h1>\u793a\u4f8b\u4ee3\u7801<\/h1>\n<pre class=\"post-pre\"><code>.\r\n\u251c\u2500\u2500 .github\r\n\u2502   \u251c\u2500\u2500 scripts\r\n\u2502   \u2502   \u2514\u2500\u2500 tfwrapper.sh\r\n\u2502   \u2514\u2500\u2500 workflows\r\n\u2502       \u2514\u2500\u2500 plan.yml\r\n\u2514\u2500\u2500 app\r\n    \u251c\u2500\u2500 envs\r\n    \u2502   \u251c\u2500\u2500 dev\r\n    \u2502   \u2502   \u251c\u2500\u2500 app\r\n    \u2502   \u2502   \u2502   \u251c\u2500\u2500 \u3007\u3007.tf\r\n    \u2502   \u2502   \u2502   \u2514\u2500\u2500 terragrunt.hcl\r\n    \u2502   \u2502   \u251c\u2500\u2500 cicd\r\n    \u2502   \u2502   \u2502   \u251c\u2500\u2500 \u3007\u3007.tf\r\n    \u2502   \u2502   \u2502   \u2514\u2500\u2500 terragrunt.hcl\r\n    \u2502   \u2502   \u251c\u2500\u2500 db\r\n    \u2502   \u2502   \u2502   \u251c\u2500\u2500 \u3007\u3007.tf\r\n    \u2502   \u2502   \u2502   \u2514\u2500\u2500 terragrunt.hcl\r\n    \u2502   \u2502   \u2514\u2500\u2500 ...\r\n    \u2502   \u2514\u2500\u2500 prod\r\n    \u251c\u2500\u2500 modules\r\n    \u2502   \u251c\u2500\u2500 acm\r\n    \u2502   \u2502   \u251c\u2500\u2500 main.tf\r\n    \u2502   \u2502   \u251c\u2500\u2500 outputs.tf\r\n    \u2502   \u2502   \u2514\u2500\u2500 variables.tf\r\n    \u2502   \u251c\u2500\u2500 cloudfront\r\n    \u2502   \u251c\u2500\u2500 cognito\r\n    \u2502   \u2514\u2500\u2500 ...\r\n    \u2514\u2500\u2500 shared\r\n        \u251c\u2500\u2500 provider.tf\r\n        \u251c\u2500\u2500 variables.tf\r\n        \u2514\u2500\u2500 version.tf\r\n\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Terraform plan<\/span>\r\n<span class=\"na\">on<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">pull_request<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">branches<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">main<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">develop<\/span>\r\n    <span class=\"na\">types<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">opened<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">synchronize<\/span>\r\n\r\n<span class=\"na\">env<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">AWS_REGION<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ap-northeast-1<\/span>\r\n  <span class=\"na\">PROJECT<\/span><span class=\"pi\">:<\/span> <span class=\"s\">sample<\/span>\r\n  <span class=\"na\">TF_VERSION<\/span><span class=\"pi\">:<\/span> <span class=\"s\">1.3.7<\/span>\r\n  <span class=\"na\">TG_VERSION<\/span><span class=\"pi\">:<\/span> <span class=\"s\">0.43.0<\/span>\r\n  <span class=\"na\">TFCMT_VERSION<\/span><span class=\"pi\">:<\/span> <span class=\"s\">4.0.1<\/span>\r\n\r\n<span class=\"na\">permissions<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">id-token<\/span><span class=\"pi\">:<\/span> <span class=\"s\">write<\/span>\r\n  <span class=\"na\">contents<\/span><span class=\"pi\">:<\/span> <span class=\"s\">read<\/span>\r\n  <span class=\"na\">pull-requests<\/span><span class=\"pi\">:<\/span> <span class=\"s\">write<\/span>\r\n\r\n<span class=\"na\">jobs<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">plan<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Terraform plan<\/span>\r\n    <span class=\"na\">runs-on<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ubuntu-latest<\/span>\r\n\r\n    <span class=\"na\">steps<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Set env vars for dev<\/span>\r\n        <span class=\"na\">if<\/span><span class=\"pi\">:<\/span> <span class=\"s\">github.base_ref == 'develop'<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n          <span class=\"s\">echo \"ENVIRONMENT=dev\" &gt;&gt; $GITHUB_ENV<\/span>\r\n          <span class=\"s\">echo \"AWS_ACCOUNT_ID=123456789012\" &gt;&gt; $GITHUB_ENV<\/span>\r\n          <span class=\"s\">echo \"WORK_DIR=app\/envs\/dev\" &gt;&gt; $GITHUB_ENV<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Set env vars for prod<\/span>\r\n        <span class=\"na\">if<\/span><span class=\"pi\">:<\/span> <span class=\"s\">github.base_ref == 'main'<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n          <span class=\"s\">echo \"ENVIRONMENT=dev\" &gt;&gt; $GITHUB_ENV<\/span>\r\n          <span class=\"s\">echo \"AWS_ACCOUNT_ID=123456789012\" &gt;&gt; $GITHUB_ENV<\/span>\r\n          <span class=\"s\">echo \"WORK_DIR=app\/envs\/prod\" &gt;&gt; $GITHUB_ENV<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Checkout<\/span>\r\n        <span class=\"na\">uses<\/span><span class=\"pi\">:<\/span> <span class=\"s\">actions\/checkout@v3<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Setup Terraform<\/span>\r\n        <span class=\"na\">uses<\/span><span class=\"pi\">:<\/span> <span class=\"s\">hashicorp\/setup-Terraform@v1<\/span>\r\n        <span class=\"na\">with<\/span><span class=\"pi\">:<\/span>\r\n          <span class=\"na\">terraform_version<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ env.TF_VERSION }}<\/span>\r\n          <span class=\"na\">terraform_wrapper<\/span><span class=\"pi\">:<\/span> <span class=\"kc\">false<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Setup Terragrunt<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n          <span class=\"s\">sudo wget -q -O \/bin\/terragrunt \"https:\/\/github.com\/gruntwork-io\/terragrunt\/releases\/download\/v${TG_VERSION}\/terragrunt_linux_amd64\"<\/span>\r\n          <span class=\"s\">sudo chmod +x \/bin\/terragrunt<\/span>\r\n          <span class=\"s\">terragrunt --version<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Setup tfcmt<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n          <span class=\"s\">wget \"https:\/\/github.com\/suzuki-shunsuke\/tfcmt\/releases\/download\/v${TFCMT_VERSION}\/tfcmt_linux_amd64.tar.gz\" -O \/tmp\/tfcmt.tar.gz<\/span>\r\n          <span class=\"s\">tar xzf \/tmp\/tfcmt.tar.gz -C \/tmp<\/span>\r\n          <span class=\"s\">mv \/tmp\/tfcmt \/usr\/local\/bin<\/span>\r\n          <span class=\"s\">tfcmt --version<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Configure AWS credentials<\/span>\r\n        <span class=\"na\">uses<\/span><span class=\"pi\">:<\/span> <span class=\"s\">aws-actions\/configure-aws-credentials@master<\/span>\r\n        <span class=\"na\">with<\/span><span class=\"pi\">:<\/span>\r\n          <span class=\"na\">role-to-assume<\/span><span class=\"pi\">:<\/span> <span class=\"s\">arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role\/${{ env.PROJECT }}-${{ env.ENVIRONMENT }}-github-actions-terraform-role<\/span>\r\n          <span class=\"na\">role-session-name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ env.PROJECT }}-${{ env.ENVIRONMENT }}-github-actions-terraform-session<\/span>\r\n          <span class=\"na\">aws-region<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ env.AWS_REGION }}<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Terragrunt init<\/span>\r\n        <span class=\"na\">working-directory<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ env.WORK_DIR }}<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"s\">terragrunt run-all init<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Check terraform fmt<\/span>\r\n        <span class=\"na\">working-directory<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ env.WORK_DIR }}<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"s\">terraform fmt -check -recursive<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Terragrunt validate<\/span>\r\n        <span class=\"na\">working-directory<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ env.WORK_DIR }}<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"s\">terragrunt run-all validate<\/span>\r\n\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Terragrunt plan<\/span>\r\n        <span class=\"na\">working-directory<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ env.WORK_DIR }}<\/span>\r\n        <span class=\"na\">env<\/span><span class=\"pi\">:<\/span>\r\n          <span class=\"na\">GITHUB_TOKEN<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${{ secrets.GITHUB_TOKEN }}<\/span>\r\n        <span class=\"na\">run<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n          <span class=\"s\">terragrunt run-all plan --terragrunt-tfpath $GITHUB_WORKSPACE\/.github\/scripts\/tfwrapper.sh<\/span>\r\n\r\n<\/code><\/pre>\n<h1>\u8bf7\u53c2\u8003<\/h1>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6211\u60f3\u505a\u7684\u4e8b\u60c5 \u6211\u5728\u4f7f\u7528GitHub Actions\u4e2d\u7684Terragrunt\u65f6\uff0c\u6b63\u5728\u7814\u7a76\u5982\u4f55\u5728pull requ [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-48524","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u5728github-actions\u4e2d\u4f7f\u7528terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb\" \/>\n<meta property=\"og:description\" content=\"\u6211\u60f3\u505a\u7684\u4e8b\u60c5 \u6211\u5728\u4f7f\u7528GitHub Actions\u4e2d\u7684Terragrunt\u65f6\uff0c\u6b63\u5728\u7814\u7a76\u5982\u4f55\u5728pull requ [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u5728github-actions\u4e2d\u4f7f\u7528terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2024-01-11T16:34:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-29T19:49:59+00:00\" \/>\n<meta name=\"author\" content=\"\u79d1, \u9896\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u79d1, \u9896\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/\",\"name\":\"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2024-01-11T16:34:47+00:00\",\"dateModified\":\"2024-04-29T19:49:59+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\",\"name\":\"\u79d1, \u9896\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"caption\":\"\u79d1, \u9896\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u5728github-actions\u4e2d\u4f7f\u7528terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb","og_description":"\u6211\u60f3\u505a\u7684\u4e8b\u60c5 \u6211\u5728\u4f7f\u7528GitHub Actions\u4e2d\u7684Terragrunt\u65f6\uff0c\u6b63\u5728\u7814\u7a76\u5982\u4f55\u5728pull requ [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u5728github-actions\u4e2d\u4f7f\u7528terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2024-01-11T16:34:47+00:00","article_modified_time":"2024-04-29T19:49:59+00:00","author":"\u79d1, \u9896","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u79d1, \u9896","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"2 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/","name":"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2024-01-11T16:34:47+00:00","dateModified":"2024-04-29T19:49:59+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5982\u4f55\u5728GitHub Actions\u4e2d\u4f7f\u7528Terragrunt\u548ctfcmt\u6765\u4f7f\u8ba1\u5212\u7ed3\u679c\u66f4\u6613\u4e8e\u9605\u8bfb"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e","name":"\u79d1, \u9896","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","caption":"\u79d1, \u9896"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e5%9c%a8github-actions%e4%b8%ad%e4%bd%bf%e7%94%a8terragrunt%e5%92%8ctfcmt%e6%9d%a5%e4%bd%bf%e8%ae%a1%e5%88%92%e7%bb%93%e6%9e%9c%e6%9b%b4%e6%98%93%e4%ba%8e%e9%98%85%e8%af%bb%e3%80%82\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48524","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=48524"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48524\/revisions"}],"predecessor-version":[{"id":89505,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48524\/revisions\/89505"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=48524"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=48524"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=48524"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}