{"id":48680,"date":"2024-01-15T04:07:12","date_gmt":"2023-11-21T05:59:04","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/"},"modified":"2024-05-04T18:27:52","modified_gmt":"2024-05-04T10:27:52","slug":"%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/","title":{"rendered":"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c"},"content":{"rendered":"<p>\u8fd9\u7bc7\u6587\u7ae0\u7684\u5185\u5bb9\u9002\u7528\u4e8e terraform 0.9.0 \u7248\u672c\u4ee5\u4e0b\u3002\u867d\u7136\u5728 terraform 0.9.x \u7248\u672c\u4e2d\uff0c\u5927\u81f4\u7684\u6d41\u7a0b\u4ecd\u7136\u76f8\u540c\uff0c\u4f46\u662f\u5728\u540e\u7aef\u65b9\u9762\u6709\u4e00\u4e9b\u6539\u52a8\uff0c\u5e76\u4e14\u6211\u4eec\u8ba1\u5212\u5c06\u6765\u4f1a\u8fdb\u884c\u76f8\u5e94\u7684\u66f4\u65b0\u3002<\/p>\n<p>\u4ee5\u4e0b\u662f\u5bf9\u7ed9\u5b9a\u7684\u5185\u5bb9\u8fdb\u884c\u4e2d\u6587\u7ffb\u8bd1\u7684\u4e00\u4e2a\u9009\u62e9\uff1a<br \/>\n==========================================<\/p>\n<p>Terraform\u662f\u4e00\u79cd\u5de5\u5177\uff0c\u53ef\u4ee5\u901a\u8fc7\u4ee3\u7801\u8868\u8fbe\u548c\u7ba1\u7406\u57fa\u7840\u8bbe\u65bd\u7684\u6784\u5efa\u548c\u914d\u7f6e\u3002\u5b83\u652f\u6301\u591a\u79cd\u73af\u5883\uff0c\u5982AWS\u3001Azure\u548cHeroku\u3002<\/p>\n<p>\u8fd9\u4efd\u8d44\u6599\u662f\u4e3a\u4e86\u5728Rabbit House\u516c\u53f8\u5185\u8fdb\u884c\u7684\u3001\u7528\u4e8e\u5904\u7406AWS\u8d44\u6e90\u7684terraform\u64cd\u4f5c\u7684\u5b9e\u8df5\u800c\u521b\u5efa\u7684\u3002\u6211\u8ba4\u4e3a\u5bf9\u4e8e\u90a3\u4e9b\u60f3\u8981\u4f7f\u7528\u4ee3\u7801\u6765\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u4eba\u6765\u8bf4\uff0c\u6709\u4e9b\u4eba\u53ef\u80fd\u4f1a\u89c9\u5f97\u8fd9\u6837\u7684\u5de5\u5177\u5f88\u9ebb\u70e6\uff0c\u6216\u8005\u5f88\u5bb9\u6613\u53d8\u5f97\u65e0\u6cd5\u4f7f\u7528\uff0c\u4f46\u662fterraform\u975e\u5e38\u7b80\u5355\uff0c\u5b66\u4e60\u6210\u672c\u975e\u5e38\u4f4e\u3002\u800c\u4e14\uff0c\u6211\u8ba4\u4e3a\u901a\u8fc7\u5c06AWS\u914d\u7f6e\u7f16\u7801\u5316\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u66f4\u6df1\u5165\u5730\u7406\u89e3AWS\u7684\u5404\u4e2a\u65b9\u9762\u3002<\/p>\n<p>\u4f60\u4e3a\u4ec0\u4e48\u4e0d\u8d81\u6b64\u673a\u4f1a\u5c1d\u8bd5\u4e00\u4e0b terraform \u5462\uff1f\u6309\u7167\u8fd9\u7bc7\u6587\u7ae0\u7684\u6307\u5f15\u8f93\u5165\u547d\u4ee4\uff0c\u4f60\u5f88\u5feb\u5c31\u80fd\u719f\u7ec3\u5730\u4f7f\u7528 terraform\uff0c\u53ef\u80fd\u4e0d\u5230\u4e00\u4e2a\u5c0f\u65f6\u5c31\u80fd\u638c\u63e1\u3002<\/p>\n<h2>1. \u73af\u5883\u5efa\u8bbe<\/h2>\n<p>\u5728\u8fd9\u4e2a\u5b9e\u8df5\u9879\u76ee\u4e2d\uff0c\u6211\u4eec\u5c06\u4ee5 terraform v0.7.4 \u4e3a\u57fa\u7840\u8fdb\u884c\u8bb2\u89e3\u3002<\/p>\n<h3>\u5bf9\u4e8e Mac \u7684\u60c5\u51b5\u6765\u8bf4<\/h3>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">https:\/\/www.terraform.io\/downloads.html<\/ul>\n<\/li>\n<\/ul>\n<p>brew install terraform \u3067\u3082\u53ef<\/p>\n<h3>\u5728Windows\u7684\u60c5\u51b5\u4e0b<\/h3>\n<p>\u8bf7\u8bbf\u95ee\u4ee5\u4e0b\u94fe\u63a5\u83b7\u53d6\u6700\u65b0\u7248\u672c\u7684Terraform\u8f6f\u4ef6\uff1ahttps:\/\/www.terraform.io\/downloads.html<\/p>\n<h3>AWS\u51c6\u5907<\/h3>\n<p>\u4e8b\u5148\u521b\u5efa\u597d\u5c06\u7528\u4e8eTerraform\u7684IAM\u7528\u6237\u3002<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u8bbf\u95eeIAM\u7528\u6237\u7ba1\u7406\u9875\u9762<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u521b\u5efa\u65b0\u7528\u6237<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u9644\u52a0\u5fc5\u8981\u7684\u7b56\u7565<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\u521b\u5efa\u8bbf\u95ee\u5bc6\u94a5\u548c\u79d8\u5bc6\u5bc6\u94a5<\/ol>\n<h2>\u7ba1\u7406S3\u5b58\u50a8\u6876<\/h2>\n<p>\u9996\u5148\uff0c\u6211\u4eec\u521b\u5efa\u3001\u66f4\u6539\u5e76\u5c1d\u8bd5\u7834\u574f\u4e00\u4e2a S3 \u5b58\u50a8\u6876\u3002\u4f5c\u4e3a\u51c6\u5907\u5de5\u4f5c\uff0c\u8bf7\u521b\u5efa\u4e00\u4e2a\u5408\u9002\u7684\u5de5\u4f5c\u76ee\u5f55\u3002\u7136\u540e\uff0c\u6211\u4eec\u7f16\u5199\u8bbf\u95ee AWS \u8d44\u6e90\u6240\u9700\u7684\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code>provider \"aws\" {\r\n  region     = \"ap-northeast-1\"\r\n  access_key = \"***************\"\r\n  secret_key = \"***************\"\r\n}\r\n<\/code><\/pre>\n<h3>\u521b\u5efa\u4e00\u4e2aS3\u5b58\u50a8\u6876\u3002<\/h3>\n<p>\u6211\u4eec\u7acb\u5373\u521b\u5efa\u4e00\u4e2a S3 \u5b58\u50a8\u6876\u5427\u3002\u8bf7\u521b\u5efa\u4e00\u4e2a\u5982\u4e0b\u6240\u793a\u7684\u6587\u4ef6\u3002\u4f46\u662f\uff0c\u8bf7\u786e\u4fdd\u5b58\u50a8\u6876\u7684\u540d\u79f0\u5728\u5168\u7403\u8303\u56f4\u5185\u662f\u552f\u4e00\u7684\u3002<\/p>\n<pre class=\"post-pre\"><code>resource \"aws_s3_bucket\" \"terraform_tutorial\" {\r\n    bucket = \"com.github.53ningen.terraform.tutorial\" # S3 bucket \u540d\u306f global \u3067\u4e00\u610f\u306b\u306a\u308b\u3088\u3046\u306b\r\n    acl = \"private\"\r\n    versioning {\r\n        enabled = true\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>\u5982\u679c\u6309\u7167\u4ee5\u4e0a\u7684\u65b9\u5f0f\u521b\u5efa\u4e86\u6587\u4ef6\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528terraform validate\u547d\u4ee4\u6765\u786e\u8ba4\u662f\u5426\u6b63\u786e\u5730\u7f16\u5199\u4e86.tf\u6587\u4ef6\u3002\u5982\u679c\u6309\u7167\u4e0a\u8ff0\u65b9\u5f0f\u7f16\u5199\uff0c\u6211\u76f8\u4fe1\u547d\u4ee4\u5e94\u8be5\u80fd\u591f\u6b63\u5e38\u6267\u884c\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u901a\u8fc7\u6267\u884cterraform plan\u547d\u4ee4\u6765\u786e\u8ba4\u5c06\u8981\u6267\u884c\u7684\u64cd\u4f5c\u3002\u8fd9\u4e2a\u6b65\u9aa4\u59cb\u7ec8\u662f\u5b89\u5168\u7684\uff0c\u5e76\u4e14\u53ea\u4f1a\u5bf9AWS\u8fdb\u884c\u4fe1\u606f\u7684\u8bfb\u53d6\u64cd\u4f5c\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform plan\r\nRefreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but\r\nwill not be persisted to local or remote state storage.\r\n\r\n\r\nThe Terraform execution plan has been generated and is shown below.\r\nResources are shown in alphabetical order for quick scanning. Green resources\r\nwill be created (or destroyed and then created if an existing resource\r\nexists), yellow resources are being changed in-place, and red resources\r\nwill be destroyed. Cyan entries are data sources to be read.\r\n\r\nNote: You didn't specify an \"-out\" parameter to save this plan, so when\r\n\"apply\" is called, Terraform can't guarantee this is what will execute.\r\n\r\n+ aws_s3_bucket.terraform_tutorial\r\n    acceleration_status:         \"&lt;computed&gt;\"\r\n    acl:                         \"private\"\r\n    arn:                         \"&lt;computed&gt;\"\r\n    bucket:                      \"com.github.53ningen.terraform.tutorial\"\r\n    force_destroy:               \"false\"\r\n    hosted_zone_id:              \"&lt;computed&gt;\"\r\n    policy:                      \"&lt;computed&gt;\"\r\n    region:                      \"&lt;computed&gt;\"\r\n    request_payer:               \"&lt;computed&gt;\"\r\n    versioning.#:                \"1\"\r\n    versioning.69840937.enabled: \"true\"\r\n    website_domain:              \"&lt;computed&gt;\"\r\n    website_endpoint:            \"&lt;computed&gt;\"\r\n\r\n\r\nPlan: 1 to add, 0 to change, 0 to destroy.\r\n<\/code><\/pre>\n<p>\u6839\u636e aws_s3_bucket.terraform_tutorial \u7684\u8bbe\u5b9a\uff0c\u6211\u4eec\u786e\u8ba4 S3 \u5b58\u50a8\u6876\u5df2\u7ecf\u521b\u5efa\u6210\u529f\u4e86\u3002\u73b0\u5728\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8fd0\u884c terraform apply \u547d\u4ee4\u6765\u5b9e\u9645\u6267\u884c\u5b83\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform apply\r\naws_s3_bucket.terraform_tutorial: Creating...\r\n  acceleration_status:         \"\" =&gt; \"&lt;computed&gt;\"\r\n  acl:                         \"\" =&gt; \"private\"\r\n  arn:                         \"\" =&gt; \"&lt;computed&gt;\"\r\n  bucket:                      \"\" =&gt; \"com.github.53ningen.terraform.tutorial\"\r\n  force_destroy:               \"\" =&gt; \"false\"\r\n  hosted_zone_id:              \"\" =&gt; \"&lt;computed&gt;\"\r\n  policy:                      \"\" =&gt; \"&lt;computed&gt;\"\r\n  region:                      \"\" =&gt; \"&lt;computed&gt;\"\r\n  request_payer:               \"\" =&gt; \"&lt;computed&gt;\"\r\n  versioning.#:                \"\" =&gt; \"1\"\r\n  versioning.69840937.enabled: \"\" =&gt; \"true\"\r\n  website_domain:              \"\" =&gt; \"&lt;computed&gt;\"\r\n  website_endpoint:            \"\" =&gt; \"&lt;computed&gt;\"\r\naws_s3_bucket.terraform_tutorial: Creation complete\r\n\r\nApply complete! Resources: 1 added, 0 changed, 0 destroyed.\r\n\r\nThe state of your infrastructure has been saved to the path\r\nbelow. This state is required to modify and destroy your\r\ninfrastructure, so keep it safe. To inspect the complete state\r\nuse the `terraform show` command.\r\n\r\nState path: terraform.tfstate\r\n<\/code><\/pre>\n<p>\u7531\u4e8e\u4e8b\u60c5\u65e0\u5927\u788d\u4e14\u6210\u529f\u4f3c\u4e4e\u5df2\u7ecf\u5b9e\u73b0\uff0c\u6211\u4eec\u5148\u4eceAWS CLI\u786e\u8ba4\u4e00\u4e0bS3\u5b58\u50a8\u6876\u662f\u5426\u771f\u5b9e\u5b58\u5728\u3002<\/p>\n<pre class=\"post-pre\"><code>% aws s3 ls\r\n...\r\n2016-10-10 17:28:13 com.github.53ningen.terraform.tutorial\r\n...\r\n<\/code><\/pre>\n<p>\u901a\u8fc7s3.tf\u6587\u4ef6\u6211\u53ef\u4ee5\u786e\u8ba4\u5df2\u7ecf\u521b\u5efa\u4e86\u4e00\u4e2a\u540d\u4e3acom.github.53ningen.terraform.tutorial\u7684bucket\u3002\u90a3\u4e48\uff0c\u5728\u6210\u529f\u6267\u884cterraform apply\u540e\uff0c\u6211\u8ba4\u4e3a\u4f1a\u751f\u6210\u4e00\u4e2a\u540d\u4e3aterraform.tfstate\u7684\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>% ls -a\r\n.  ..  .git  s3.tf  terraform.tfstate  variable.tf\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u6587\u4ef6\u7684\u5185\u5bb9\u662f\u4e00\u4e2a\u4fdd\u5b58\u8fdc\u7a0b\uff08\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u662fAWS\uff09\u72b6\u6001\u7684\u6587\u4ef6\u3002\u7531\u4e8e\u5b83\u5305\u542b\u8bbf\u95ee\u5bc6\u94a5\u548c\u5bc6\u94a5\u7b49\u4fe1\u606f\uff0c\u6240\u4ee5\u8bf7\u5c06\u5176\u6392\u9664\u5728git\u7ba1\u7406\u4e4b\u5916\u3002\u5173\u4e8e\u8fd9\u4e2a\u6587\u4ef6\u7684\u7ba1\u7406\uff0c\u6211\u4eec\u5c06\u5728\u540e\u9762\u7684&#8221;\u7ba1\u7406\u8fdc\u7a0b\u72b6\u6001&#8221;\u90e8\u5206\u8fdb\u884c\u89e3\u91ca\u3002\u6682\u65f6\u5148\u6dfb\u52a0\u4ee5\u4e0b\u7c7b\u578b\u7684.gitignore\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>.DS_Store\r\n*.tfstate\r\n*.tfstate.backup\r\nvendor\/bundle\r\n.bundle\/\r\nconfig.tfvars\r\n.terraform\/\r\n<\/code><\/pre>\n<h3>\u4fee\u6539S3\u5b58\u50a8\u6876\u7684\u72b6\u6001\u3002<\/h3>\n<p>\u6211\u4eec\u4e4b\u524d\u521b\u5efa\u7684S3 bucket\u5df2\u7ecf\u542f\u7528\u4e86\u7248\u672c\u63a7\u5236\uff0c\u73b0\u5728\u8ba9\u6211\u4eec\u5c1d\u8bd5\u7981\u7528\u5b83\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4fee\u6539s3.tf\u6587\u4ef6\u6765\u5b9e\u73b0\u8fd9\u4e00\u70b9\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"p\">resource \"aws_s3_bucket\" \"terraform_tutorial\" {\r\n<\/span>    bucket = \"com.github.53ningen.terraform.tutorial\" # S3 bucket \u540d\u306f global \u3067\u4e00\u610f\u306b\u306a\u308b\u3088\u3046\u306b\r\n    acl = \"private\"\r\n    versioning {\r\n<span class=\"gd\">-       enabled = true\r\n<\/span><span class=\"gi\">+       enabled = false\r\n<\/span>   }\r\n<span class=\"err\">}<\/span>\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u4f7f\u7528 terraform validate \u547d\u4ee4\u9a8c\u8bc1 tf \u6587\u4ef6\u7684\u8bed\u6cd5\uff0c\u5e76\u4f7f\u7528 terraform plan \u547d\u4ee4\u786e\u5b9a\u5c06\u5bf9 AWS \u8d44\u6e90\u8fdb\u884c\u54ea\u4e9b\u66f4\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform plan\r\nRefreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but\r\nwill not be persisted to local or remote state storage.\r\n\r\naws_s3_bucket.terraform_tutorial: Refreshing state... (ID: com.github.53ningen.terraform.tutorial)\r\n\r\nThe Terraform execution plan has been generated and is shown below.\r\nResources are shown in alphabetical order for quick scanning. Green resources\r\nwill be created (or destroyed and then created if an existing resource\r\nexists), yellow resources are being changed in-place, and red resources\r\nwill be destroyed. Cyan entries are data sources to be read.\r\n\r\nNote: You didn't specify an \"-out\" parameter to save this plan, so when\r\n\"apply\" is called, Terraform can't guarantee this is what will execute.\r\n\r\n~ aws_s3_bucket.terraform_tutorial\r\n    versioning.2972667452.enabled: \"\" =&gt; \"false\"\r\n    versioning.69840937.enabled:   \"true\" =&gt; \"false\"\r\n\r\n\r\nPlan: 0 to add, 1 to change, 0 to destroy.\r\n<\/code><\/pre>\n<p>\u8ba1\u5212\uff1a0\u4ee3\u8868\u6dfb\u52a0\uff0c1\u4ee3\u8868\u66f4\u6539\uff0c0\u4ee3\u8868\u5220\u9664\u3002\u7531\u4e8e\u8fd9\u4e2a\u89c4\u5212\uff0c\u73b0\u6709\u7684S3\u4e0d\u4f1a\u88ab\u5220\u9664\uff0c\u53ea\u4f1a\u66f4\u6539\u663e\u793a\u7684\u53c2\u6570\u3002\u786e\u8ba4\u540e\uff0c\u53ea\u9700\u6267\u884c\u5e94\u7528\u7a0b\u5e8f\uff0cS3\u72b6\u6001\u7684\u66f4\u6539\u5373\u53ef\u5b8c\u6210\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform apply\r\naws_s3_bucket.terraform_tutorial: Refreshing state... (ID: com.github.53ningen.terraform.tutorial)\r\naws_s3_bucket.terraform_tutorial: Modifying...\r\n  versioning.2972667452.enabled: \"\" =&gt; \"false\"\r\n  versioning.69840937.enabled:   \"true\" =&gt; \"false\"\r\naws_s3_bucket.terraform_tutorial: Modifications complete\r\n\r\nApply complete! Resources: 0 added, 1 changed, 0 destroyed.\r\n\r\nThe state of your infrastructure has been saved to the path\r\nbelow. This state is required to modify and destroy your\r\ninfrastructure, so keep it safe. To inspect the complete state\r\nuse the `terraform show` command.\r\n\r\nState path: terraform.tfstate\r\n<\/code><\/pre>\n<h3>\u9500\u6bc1S3\u5b58\u50a8\u6876\u3002<\/h3>\n<p>\u597d\u7684\uff0c\u6211\u4eec\u4e4b\u524d\u4f5c\u4e3a\u6559\u7a0b\u521b\u5efa\u4e86\u4e00\u4e2a S3 bucket\uff0c\u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u5220\u9664\u5b83\u3002\u53ef\u4ee5\u4f7f\u7528 terraform destroy \u547d\u4ee4\u6765\u6267\u884c\u5220\u9664\u64cd\u4f5c\uff0c\u4f46\u662f\u5728\u6267\u884c\u4e4b\u524d\uff0c\u6700\u597d\u5148\u786e\u8ba4\u4e00\u4e0b\u3002\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u5c1d\u8bd5\u6267\u884c terraform plan &#8211;destroy \u547d\u4ee4\u3002\u8fd9\u6837\u5c31\u53ef\u4ee5\u67e5\u770b terraform destroy \u7684\u6267\u884c\u8ba1\u5212\u4e86\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform plan --destroy\r\nRefreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but\r\nwill not be persisted to local or remote state storage.\r\n\r\naws_s3_bucket.terraform_tutorial_tfsate: Refreshing state... (ID: com.github.53ningen.terraform.tutorial.tfstate)\r\n\r\nThe Terraform execution plan has been generated and is shown below.\r\nResources are shown in alphabetical order for quick scanning. Green resources\r\nwill be created (or destroyed and then created if an existing resource\r\nexists), yellow resources are being changed in-place, and red resources\r\nwill be destroyed. Cyan entries are data sources to be read.\r\n\r\nNote: You didn't specify an \"-out\" parameter to save this plan, so when\r\n\"apply\" is called, Terraform can't guarantee this is what will execute.\r\n\r\n- aws_s3_bucket.terraform_tutorial_tfsate\r\n\r\n\r\nPlan: 0 to add, 0 to change, 1 to destroy.\r\n<\/code><\/pre>\n<p>\u5982\u679c\u6267\u884c\u8ba1\u5212\u770b\u8d77\u6765\u6ca1\u6709\u95ee\u9898\uff0c\u5c31\u5c1d\u8bd5\u8fd0\u884cterraform destroy\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform destroy\r\nDo you really want to destroy?\r\n  Terraform will delete all your managed infrastructure.\r\n  There is no undo. Only 'yes' will be accepted to confirm.\r\n\r\n  Enter a value: yes\r\n\r\naws_s3_bucket.terraform_tutorial: Refreshing state... (ID: com.github.53ningen.terraform.tutorial)\r\naws_s3_bucket.terraform_tutorial: Destroying...\r\naws_s3_bucket.terraform_tutorial: Destruction complete\r\n\r\nDestroy complete! Resources: 1 destroyed.\r\n<\/code><\/pre>\n<p>\u5f53\u8fd0\u884c &#8220;terraform destroy&#8221; \u547d\u4ee4\u65f6\uff0c\u7cfb\u7edf\u4f1a\u8be2\u95ee\u60a8\u662f\u5426\u786e\u8ba4\u8981\u5220\u9664\u8d44\u6e90\u3002\u5982\u679c\u60a8\u8f93\u5165 &#8220;yes&#8221;\uff0c\u90a3\u4e48\u6b64\u524d\u521b\u5efa\u7684S3\u5b58\u50a8\u6876\u5c06\u88ab\u5220\u9664\u3002<\/p>\n<h3>2-4. \u683c\u5f0f\u5316tf\u6587\u4ef6\u3002<\/h3>\n<p>\u4f7f\u7528Terrform fmt\u547d\u4ee4\u53ef\u4ee5\u683c\u5f0f\u5316\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform fmt\r\nremote_state.tf\r\nvariable.tf\r\n<\/code><\/pre>\n<h3>2-5. Terraform\u7684\u57fa\u672c\u547d\u4ee4\u603b\u7ed3<\/h3>\n<p>\u6211\u8ba4\u4e3a\u60a8\u5df2\u7ecf\u7406\u89e3\u4e86\u4e0a\u8ff0\u5185\u5bb9\u4e2d Terraform \u7684\u57fa\u672c\u4e94\u4e2a\u547d\u4ee4\u3002\u603b\u7ed3\u5982\u4e0b\uff1a<\/p>\n<p>terraform validate: .tf \u30d5\u30a1\u30a4\u30eb\u306e\u30b7\u30f3\u30bf\u30c3\u30af\u30b9\u3092\u691c\u8a3c\u3059\u308b<\/p>\n<p>terraform plan: terraform \u304c\u3053\u308c\u304b\u3089\u884c\u3046\u5b9f\u884c\u8a08\u753b\u3092\u8868\u793a\u3059\u308b\u3002&#8211;destroy \u30aa\u30d7\u30b7\u30e7\u30f3\u3067 destroy \u6642\u306e\u5b9f\u884c\u8a08\u753b\u3092\u8868\u793a\u3067\u304d\u308b\u3002<\/p>\n<p>terraform apply: plan \u3092\u5b9f\u884c\u3059\u308b\u3002<\/p>\n<p>terraform destroy: terraform \u3067\u4f5c\u3063\u305f\u30ea\u30bd\u30fc\u30b9\u3092\u7834\u68c4\u3059\u308b<\/p>\n<p>terraform fmt: tf\u30d5\u30a1\u30a4\u30eb\u3092\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3059\u308b<\/p>\n<p>\u8bf7\u52a1\u5fc5\u5728\u5e94\u7528\u4e4b\u524d\u4ed4\u7ec6\u67e5\u770b\u6267\u884c\u8ba1\u5212\u3002\u6211\u8ba4\u4e3a\u51e0\u4e4e\u4e0d\u4f1a\u4f7f\u7528 destroy \u6307\u4ee4\u3002\u540c\u65f6\uff0c\u8bf7\u52ff\u5c06 terraform.tfstate \u6587\u4ef6\u653e\u5165 git \u8fdb\u884c\u7ba1\u7406\uff0c\u4e5f\u4e0d\u8981\u4f7f\u5176\u66b4\u9732\u7ed9\u4ed6\u4eba\u3002<\/p>\n<h2>\u7ba1\u7406\u8fdc\u7a0b\u72b6\u6001<\/h2>\n<p>terraform.tfstate \u6587\u4ef6\u662f\u7528\u6765\u7ba1\u7406\u8fdc\u7a0b\u72b6\u6001\u7684\u6587\u4ef6\u3002apply \u6210\u529f\u540e\uff0c\u5b83\u8be6\u7ec6\u8bb0\u5f55\u4e86\u6bcf\u4e2a\u8d44\u6e90\u4ee5\u53ca\u88ab\u521b\u5efa\u65f6\u4f7f\u7528\u7684\u53c2\u6570\u3002<\/p>\n<p>\u5982\u679c\u4e0d\u5c0f\u5fc3\u5220\u9664 tfstate \u6587\u4ef6\uff0cterraform \u5c06\u9519\u8bef\u5730\u8ba4\u4e3a\u5728\u8fdc\u7a0b\u8d44\u6e90\u4e0d\u5b58\u5728\uff0c\u5e76\u8bd5\u56fe\u6839\u636e tf \u6587\u4ef6\u4e2d\u7684\u5b9a\u4e49\u521b\u5efa\u65b0\u914d\u7f6e\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u9700\u8981\u4ee5\u67d0\u79cd\u65b9\u5f0f\u7ba1\u7406\u6b64\u6587\u4ef6\uff0c\u4f46\u7531\u4e8e\u5176\u4e2d\u5305\u542b\u5927\u91cf\u654f\u611f\u4fe1\u606f\uff0c\u65e0\u6cd5\u7b80\u5355\u5730\u4f7f\u7528 git \u8fdb\u884c\u7ba1\u7406\u3002<\/p>\n<p>\u6709\u591a\u79cd\u7ba1\u7406\u65b9\u6cd5\uff0c\u4f46\u5728\u8fd9\u91cc\u6211\u4eec\u5c06\u4ecb\u7ecd\u4f7f\u7528\u79c1\u6709S3\u5b58\u50a8\u6876\u6765\u7ba1\u7406\u6b64\u6587\u4ef6\u7684\u65b9\u6cd5\u3002<\/p>\n<h3>\u521b\u5efa\u4e00\u4e2a\u7528\u4e8etfsate\u7ba1\u7406\u7684S3\u5b58\u50a8\u6876\u3002<\/h3>\n<p>\u6211\u60f3\u60a8\u80af\u5b9a\u5df2\u7ecf\u5bf9\u524d\u9762\u8bb2\u8fc7\u7684S3\u5b58\u50a8\u6876\u7684\u521b\u5efa\u6709\u6240\u7406\u89e3\u4e86\u3002\u8ba9\u6211\u4eec\u8fdb\u884c\u4e00\u6b21\u590d\u4e60\u5427\u3002\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3aremote_state.tf\u7684\u6587\u4ef6\uff0c\u5185\u5bb9\u5982\u4e0b\u3002<\/p>\n<pre class=\"post-pre\"><code>resource \"aws_s3_bucket\" \"terraform_tutorial_tfsate\" {\r\n    bucket = \"com.github.53ningen.terraform.tutorial.tfstate\" # S3 bucket \u540d\u306f global \u3067\u4e00\u610f\u306b\u306a\u308b\u3088\u3046\u306b\r\n    acl = \"private\"\r\n    versioning {\r\n        enabled = true\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>\u5728\u4f7f\u7528 Terraform \u65f6\uff0c\u53ef\u4ee5\u5148\u901a\u8fc7 `terraform plan` \u547d\u4ee4\u786e\u8ba4\u6267\u884c\u8ba1\u5212\uff0c\u7136\u540e\u4f7f\u7528 `terraform apply` \u547d\u4ee4\u521b\u5efa\u5b58\u50a8\u6876\u3002\u6839\u636e Terraform \u5b98\u65b9\u6587\u6863\u7684\u63a8\u8350\uff0c\u5efa\u8bae\u542f\u7528\u7248\u672c\u63a7\u5236\u3002<\/p>\n<h3>\u8fdb\u884ctfstate\u7ba1\u7406\u8bbe\u7f6e\u3002<\/h3>\n<p>\u4e00\u65e6\u521b\u5efa\u4e86\u65e0\u4e8bS3\u5b58\u50a8\u6876\uff0c\u4f7f\u7528terraform remote config\u547d\u4ee4\u6765\u8fdb\u884ctfstate\u6587\u4ef6\u7684\u7ba1\u7406\u914d\u7f6e\u3002\u8bf7\u6839\u636e\u81ea\u5df1\u7684\u60c5\u51b5\u76f8\u5e94\u66f4\u6539\u4ee5\u4e0b\u547d\u4ee4\u4e2d\u7684\u6876\u540d\u548c\u8bbf\u95ee\u5bc6\u94a5\u7b49\u5185\u5bb9\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform remote config \\\r\n    -backend=S3 \\\r\n    -backend-config=\"bucket=com.github.53ningen.terraform.tutorial.tfstate\" \\\r\n    -backend-config=\"region=ap-northeast-1\" \\\r\n    -backend-config=\"key=terraform.tfstate\" \\\r\n    -backend-config=\"access_key=${access_key}\" \\\r\n    -backend-config=\"secret_key=${ecret_key}\"\r\nRemote state management enabled\r\nRemote state configured and pulled.\r\n<\/code><\/pre>\n<p>\u5728\u8fd9\u91cc\uff0c\u952e\uff08key\uff09\u662f\u6307\u5728S3\u4e0a\u7ba1\u7406tfstate\u6587\u4ef6\u7684\u540d\u79f0\u3002\u5982\u679c\u547d\u4ee4\u6210\u529f\u6267\u884c\uff0c\u6211\u8ba4\u4e3a\u5f53\u524d\u76ee\u5f55\u4e2d\u7684terraform.tfstate\u6587\u4ef6\u5c06\u88ab\u79fb\u52a8\u5230.terraform\u76ee\u5f55\u4e0b\u3002<\/p>\n<h3>\u5c06tfstate\u63a8\u9001\u5230\u8fdc\u7a0b<\/h3>\n<p>\u597d\u7684\uff0c\u7ba1\u7406\u8bbe\u7f6e\u5b8c\u6210\u540e\uff0c\u8ba9\u6211\u4eec\u5c06 tfstate \u6587\u4ef6\u4f20\u8f93\u5230 S3 \u4e0a\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform remote push\r\nState successfully pushed!\r\n<\/code><\/pre>\n<p>\u5982\u679c\u5bf9\u8fdc\u7a0b\u8fdb\u884cterraform apply\uff0c\u8bf7\u52a1\u5fc5\u6267\u884cterraform remote push\u3002<\/p>\n<h3>3-4. \u4ece\u8fdc\u7a0b\u4e0b\u8f7d tfstate<\/h3>\n<p>\u8fd9\u901a\u5e38\u7528\u4e8e\u591a\u4eba\u5f00\u53d1\u7684\u60c5\u51b5\uff0c\u4f8b\u5982\u5e0c\u671b\u5728\u522b\u4eba apply \u4e4b\u540e\u540c\u6b65\u8fdc\u7a0b\u72b6\u6001\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform remote pull\r\nLocal and remote state in sync\r\n<\/code><\/pre>\n<h2>\u8fdb\u884c\u66f4\u9ad8\u7ea7\u7684\u8d44\u6e90\u5b9a\u4e49<\/h2>\n<h3>4-1. \u4f7f\u7528\u53d8\u91cf<\/h3>\n<p>\u5728variable.tf\u4e2d\u76f4\u63a5\u5199\u5165\u4e86aws\u7684access_key\u548csecret_key\uff0c\u4f46\u662f\u53ef\u4ee5\u4f7f\u7528\u53d8\u91cf\u529f\u80fd\u6765\u5728\u8fd0\u884c\u65f6\u6307\u5b9a\u5b83\u4eec\u3002<\/p>\n<pre class=\"post-pre\"><code>provider \"aws\" {\r\n  region = \"ap-northeast-1\"\r\n  access_key = \"${var.access_key}\"\r\n  secret_key = \"${var.secret_key}\"\r\n}\r\n\r\nvariable \"access_key\" {}\r\nvariable \"secret_key\" {}\r\n<\/code><\/pre>\n<p>\u5728\u6267\u884cterraform plan\u4e4b\u524d\uff0c\u8bf7\u6309\u7167\u4e0a\u8ff0\u6b65\u9aa4\u5728\u5bf9\u8bdd\u6846\u4e2d\u6307\u5b9a\u6bcf\u4e2a\u53c2\u6570\u5e94\u8be5\u53d6\u54ea\u4e2a\u503c\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform plan\r\nvar.access_key\r\n  Enter a value: hoge\r\n\r\nvar.secret_key\r\n  Enter a value: fuga\r\n\r\nRefreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but\r\nwill not be persisted to local or remote state storage.\r\n\r\n...\u4ee5\u4e0b\u7565\r\n<\/code><\/pre>\n<p>\u53e6\u5916\uff0c\u8fd8\u53ef\u4ee5\u901a\u8fc7\u6307\u5b9a\u53d8\u91cf\u7684\u9ed8\u8ba4\u503c\u6765\u5b9e\u73b0\u4ee5\u4e0b\u529f\u80fd\u3002<\/p>\n<pre class=\"post-pre\"><code>provider \"aws\" {\r\n  region = \"${var.region}\"\r\n  access_key = \"${var.access_key}\"\r\n  secret_key = \"${var.secret_key}\"\r\n}\r\n\r\nvariable \"access_key\" {}\r\nvariable \"secret_key\" {}\r\nvariable \"region\" {\r\n  default = \"ap-northeast-1\"\r\n}\r\n<\/code><\/pre>\n<h3>\u4f7f\u7528\u73af\u5883\u53d8\u91cf<\/h3>\n<p>\u7531\u4e8e\u6bcf\u6b21\u90fd\u8981\u5728 CLI \u4e2d\u6307\u5b9a access_key \u548c secret_key \u6709\u4e9b\u9ebb\u70e6\uff0c\u6240\u4ee5\u4f7f\u7528\u73af\u5883\u53d8\u91cf\u4f3c\u4e4e\u66f4\u65b9\u4fbf\u3002\u5728 terraform \u4e2d\uff0c\u60a8\u53ef\u4ee5\u5728 .tf \u6587\u4ef6\u4e2d\u4f7f\u7528\u4ee5 TF_VAR_ \u4e3a\u524d\u7f00\u7684\u73af\u5883\u53d8\u91cf\u3002\u8ba9\u6211\u4eec\u7acb\u5373\u4f7f\u7528\u5b83\u6765\u4ece\u73af\u5883\u53d8\u91cf\u4e2d\u83b7\u53d6 access_key \u548c secret_key\u3002<\/p>\n<pre class=\"post-pre\"><code>% echo 'export TF_VAR_MY_AWS_ACCESS_KEY=XXXXXXXXXXX' &gt;&gt; ~\/.bash_profile\r\n% echo 'export TF_VAR_MY_AWS_SECRET_KEY=XXXXXXXXXXX' &gt;&gt; ~\/.bash_profile\r\n% source ~\/.bash_profile\r\n<\/code><\/pre>\n<p>\u63a5\u7740\u6211\u4eec\u6765\u4fee\u6539 variable.tf \u6587\u4ef6\uff0c\u4fee\u6539\u5982\u4e0b\uff1a<\/p>\n<pre class=\"post-pre\"><code>provider \"aws\" {\r\n  region = \"${var.region}\"\r\n  access_key = \"${var.MY_AWS_ACCESS_KEY}\"\r\n  secret_key = \"${var.MY_AWS_SECRET_KEY}\"\r\n}\r\n\r\nvariable \"MY_AWS_ACCESS_KEY\" {}\r\nvariable \"MY_AWS_SECRET_KEY\" {}\r\nvariable \"region\" {\r\n  default = \"ap-northeast-1\"\r\n}\r\n<\/code><\/pre>\n<p>\u5982\u679c\u80fd\u591f\u5728\u6ca1\u6709\u53d8\u91cf\u6307\u5b9a\u7684\u60c5\u51b5\u4e0b\u4f7f\u7528terraform plan\uff0c\u5219\u53ef\u4ee5\u786e\u8ba4\u73af\u5883\u53d8\u91cf\u5df2\u6210\u529f\u4f7f\u7528\u3002<\/p>\n<h3>4-3. \u8fdb\u884c\u5177\u6709\u4f9d\u5b58\u7ba1\u7406\u7684\u8d44\u6e90\u5b9a\u4e49<\/h3>\n<p>\u5728\u6784\u5efa\u66f4\u590d\u6742\u7684\u8d44\u6e90\u65f6\uff0c\u8d44\u6e90\u4e4b\u95f4\u4f1a\u4ea7\u751f\u4f9d\u8d56\u5173\u7cfb\u3002\u4f8b\u5982\uff0c\u5f53\u60f3\u8981\u4e3a\u4f7f\u7528 Terraform \u521b\u5efa\u7684 IAM \u7528\u6237\u9644\u52a0\u7b56\u7565\u65f6\uff0c\u6211\u8ba4\u4e3a\u8d44\u6e90\u4e4b\u95f4\u5b58\u5728\u4f9d\u8d56\u5173\u7cfb\u3002<\/p>\n<p>\u6211\u60f3\u73b0\u5728\u8981\u521b\u5efa\u4e00\u4e2a\u540d\u4e3acocoa\u7684IAM\u7528\u6237\u5e76\u9644\u52a0IAMReadOnlyAccess\u7b56\u7565\u3002\u5bf9\u5e94\u7684.tf\u6587\u4ef6\u53ef\u6309\u4ee5\u4e0b\u65b9\u5f0f\u63cf\u8ff0\u5373\u53ef\u3002<\/p>\n<pre class=\"post-pre\"><code># IAM \u30e6\u30fc\u30b6\u30fc\u306e\u4f5c\u6210\r\nresource \"aws_iam_user\" \"cocoa\" {\r\n  name = \"cocoa\"\r\n  path = \"\/\"\r\n}\r\n\r\n# IAM \u30dd\u30ea\u30b7\u30fc\u306e\u30a2\u30bf\u30c3\u30c1\r\nresource \"aws_iam_policy_attachment\" \"IAMReadOnlyAccess-policy-attachment\" {\r\n  name       = \"IAMReadOnlyAccess-policy-attachment\"\r\n\r\n  # IAMReadOnlyAccess \u306e ARN\r\n  policy_arn = \"arn:aws:iam::aws:policy\/IAMReadOnlyAccess\"\r\n  groups     = []\r\n\r\n  # \u4e0a\u3067\u5b9a\u7fa9\u3057\u305f cocoa \u30e6\u30fc\u30b6\u30fc\u306e name \u3092\u53c2\u7167\u3057\u3066\u3044\u308b\r\n  users      = [\"${aws_iam_user.cocoa.name}\"]  \r\n  roles      = []\r\n}\r\n<\/code><\/pre>\n<p>\u5f53\u6267\u884cterraform plan\u547d\u4ee4\u65f6\uff0c\u60a8\u5c06\u4f1a\u770b\u5230\u4f9d\u8d56\u5173\u7cfb\u5df2\u7ecf\u88ab\u89e3\u6790\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform plan\r\nRefreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but\r\nwill not be persisted to local or remote state storage.\r\n\r\naws_s3_bucket.terraform_tutorial_tfsate: Refreshing state... (ID: com.github.53ningen.terraform.tutorial.tfstate)\r\n\r\nThe Terraform execution plan has been generated and is shown below.\r\nResources are shown in alphabetical order for quick scanning. Green resources\r\nwill be created (or destroyed and then created if an existing resource\r\nexists), yellow resources are being changed in-place, and red resources\r\nwill be destroyed. Cyan entries are data sources to be read.\r\n\r\nNote: You didn't specify an \"-out\" parameter to save this plan, so when\r\n\"apply\" is called, Terraform can't guarantee this is what will execute.\r\n\r\n+ aws_iam_policy_attachment.IAMReadOnlyAccess-policy-attachment\r\n    name:             \"IAMReadOnlyAccess-policy-attachment\"\r\n    policy_arn:       \"arn:aws:iam::aws:policy\/IAMReadOnlyAccess\"\r\n    users.#:          \"1\"\r\n    users.3920907786: \"cocoa\"\r\n\r\n+ aws_iam_user.cocoa\r\n    arn:           \"&lt;computed&gt;\"\r\n    force_destroy: \"false\"\r\n    name:          \"cocoa\"\r\n    path:          \"\/\"\r\n    unique_id:     \"&lt;computed&gt;\"\r\n\r\n\r\nPlan: 2 to add, 0 to change, 0 to destroy.\r\n<\/code><\/pre>\n<h3>4-4. \u4f7f\u7528\u8bbe\u5b9a\u6587\u4ef6<\/h3>\n<p>\u5728\u5904\u7406\u590d\u6742\u8d44\u6e90\u7684\u7ba1\u7406\u65f6\uff0c\u4f7f\u7528\u53ea\u5305\u542b\u8bbe\u7f6e\u7684\u914d\u7f6e\u6587\u4ef6\u4f3c\u4e4e\u975e\u5e38\u65b9\u4fbf\u3002Terraform\u4e5f\u914d\u5907\u4e86\u4f7f\u7528\u914d\u7f6e\u6587\u4ef6\u7684\u673a\u5236\u3002\u8fd9\u6b21\u6211\u4eec\u5c06AWS\u7684\u533a\u57df\u6307\u5b9a\u5207\u5206\u5230\u914d\u7f6e\u6587\u4ef6\u4e2d\u3002\u8bf7\u5220\u9664variable.tf\u6587\u4ef6\u4e2d\u7684region\u53d8\u91cf\u7684\u9ed8\u8ba4\u503c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"p\">provider \"aws\" {\r\n<\/span>  region = \"${var.region}\"\r\n  access_key = \"${var.access_key}\"\r\n  secret_key = \"${var.secret_key}\"\r\n<span class=\"err\">}<\/span>\r\n\r\n<span class=\"p\">variable \"access_key\" {}\r\nvariable \"secret_key\" {}\r\nvariable \"region\" {\r\n<\/span><span class=\"gd\">-  default = \"ap-northeast-1\"\r\n<\/span><span class=\"err\">}<\/span>\r\n<\/code><\/pre>\n<p>\u7136\u540e\u6211\u4eec\u5c06\u5728\u540d\u4e3a config.tfvars \u7684\u6587\u4ef6\u4e2d\u8fdb\u884c\u4ee5\u4e0b\u8bbe\u7f6e\u63cf\u8ff0\u3002<\/p>\n<pre class=\"post-pre\"><code>region = \"ap-northeast-1\"\r\n<\/code><\/pre>\n<p>\u53ea\u9700\u5728 terraform plan \u6216 terraform apply \u65f6\u6307\u5b9a\u914d\u7f6e\u6587\u4ef6\u5373\u53ef\u3002\u53ef\u4ee5\u4f7f\u7528 -var-file= \u9009\u9879\u6765\u6307\u5b9a\u914d\u7f6e\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform plan -var-file=.\/config.tfvars\r\nRefreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but\r\nwill not be persisted to local or remote state storage.\r\n\r\n# \u4ee5\u4e0b\u7565\r\n<\/code><\/pre>\n<h3>4-5. \u8fdb\u884c\u4ea7\u51fa<\/h3>\n<p>\u5982\u679c\u60a8\u60f3\u83b7\u53d6\u5728\u8fd0\u884c terrform apply \u540e\u521b\u5efa\u7684\u8d44\u6e90\u7684ARN\u7b49\u4fe1\u606f\uff0c\u53ef\u4ee5\u4f7f\u7528 output \u529f\u80fd\u6765\u5b9e\u73b0\u3002\u4f8b\u5982\uff0c\u5982\u679c\u60a8\u60f3\u8f93\u51fa\u521a\u521a\u521b\u5efa\u7684 cocoa \u7528\u6237\u7684ARN\uff0c\u53ea\u9700\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\u5373\u53ef\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"p\">resource \"aws_iam_user\" \"cocoa\" {\r\n<\/span>  name = \"cocoa\"\r\n  path = \"\/\"\r\n<span class=\"err\">}<\/span>\r\n\r\n<span class=\"err\">#<\/span> IAM policy attatchments\r\n\r\nresource \"aws_iam_policy_attachment\" \"IAMReadOnlyAccess-policy-attachment\" {\r\n  name       = \"IAMReadOnlyAccess-policy-attachment\"\r\n  policy_arn = \"arn:aws:iam::aws:policy\/IAMReadOnlyAccess\"\r\n  groups     = []\r\n  users      = [\"${aws_iam_user.cocoa.name}\"]\r\n  roles      = []\r\n<span class=\"err\">}<\/span>\r\n\r\n<span class=\"gi\">+ output \"cocoa_arn\" {\r\n+   value = \"${aws_iam_user.cocoa.arn}\"\r\n+ }\r\n<\/span><\/code><\/pre>\n<p>\u6211\u4eec\u6765\u6267\u884cterraform plan\u548cterraform apply\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform apply\r\naws_iam_user.cocoa: Refreshing state... (ID: cocoa)\r\naws_s3_bucket.terraform_tutorial_tfsate: Refreshing state... (ID: com.github.53ningen.terraform.tutorial.tfstate)\r\naws_iam_policy_attachment.IAMReadOnlyAccess-policy-attachment: Refreshing state... (ID: IAMReadOnlyAccess-policy-attachment)\r\n\r\nApply complete! Resources: 0 added, 0 changed, 0 destroyed.\r\n\r\nOutputs:\r\n\r\ncocoa_arn = arn:aws:iam::XXXXXXXXXXXX:user\/cocoa\r\n<\/code><\/pre>\n<p>\u53ef\u4ee5\u786e\u8ba4ARN\u5df2\u7ecf\u88ab\u6b63\u786e\u5730\u8f93\u51fa\u3002<\/p>\n<h2>5. \u652f\u6301\u6a21\u5757\u4e0e\u591a\u4e2a\u9636\u6bb5\u7684\u9002\u914d\u80fd\u529b\u3002<\/h2>\n<p>terraform \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\u5177\u6709\u6267\u884c .tf \u6587\u4ef6\u7684\u975e\u5e38\u7b80\u5355\u7684\u884c\u4e3a\u3002\u4f46\u662f\uff0c\u7531\u4e8e\u5404\u79cd\u539f\u56e0\uff0c\u4f8b\u5982\u5e0c\u671b\u5c06\u6587\u4ef6\u4fdd\u5b58\u5728\u591a\u4e2a\u7ed3\u6784\u5316\u7684\u76ee\u5f55\u4e2d\uff0c\u6216\u8005\u53ea\u60f3\u901a\u8fc7\u66f4\u6539\u53c2\u6570\u6765\u8c03\u7528\u4ee5\u521b\u5efa\u591a\u4e2a\u9636\u6bb5\u7b49\u7b49\uff0c\u60a8\u53ef\u80fd\u5e0c\u671b\u8c03\u7528\u4f4d\u4e8e\u4e0d\u540c\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4f7f\u7528\u6a21\u5757\u529f\u80fd\u3002<\/p>\n<h3>5-1. \u4f7f\u7528\u6a21\u5757\u7684\u57fa\u672c\u77e5\u8bc6<\/h3>\n<p>\u4e3a\u4e86\u6d4b\u8bd5\u6a21\u5757\uff0c\u9996\u5148\u8ba9\u6211\u4eec\u521b\u5efa\u5982\u4e0b\u6240\u793a\u7684\u76ee\u5f55\u7ed3\u6784\u3002<\/p>\n<pre class=\"post-pre\"><code>% tree\r\n.\r\n\u251c\u2500\u2500 dev\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 modules.tf\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 variable.tf\r\n\u251c\u2500\u2500 modules\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 s3\r\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 s3.tf\r\n\u2514\u2500\u2500 prod\r\n    \u251c\u2500\u2500 modules.tf\r\n    \u2514\u2500\u2500 variable.tf\r\n<\/code><\/pre>\n<p>\u6211\u4eec\u5c06\u4e3a\u6bcf\u4e2a\u6a21\u5757\u5b9a\u4e49\u8d44\u6e90\u3002\u4f5c\u4e3a\u793a\u4f8b\uff0c\u8ba9\u6211\u4eec\u521b\u5efa dev\/prod \u65b9\u5411\u7684 S3 \u5b58\u50a8\u6876\u3002\u9996\u5148\u4ece modules\/s3\/s3.tf \u5f00\u59cb\u3002<\/p>\n<pre class=\"post-pre\"><code>resource \"aws_s3_bucket\" \"tutorial_s3\" {\r\n  bucket = \"${var.env}.53nigen.github.com.tutorial.s3\" # S3 bucket \u540d\u306f global \u3067\u4e00\u610f\u306b\u306a\u308b\u3088\u3046\u306b\r\n  acl    = \"private\"\r\n\r\n  versioning {\r\n    enabled = false\r\n  }\r\n}\r\n\r\nvariable \"env\" {}\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u6765\u7f16\u5199\u4ee3\u7801\uff0c\u5c06 modules\/s3 \u6587\u4ef6\u5939\u4e0b\u7684\u5185\u5bb9\u5206\u522b\u5bfc\u5165\u5230 dev\/modules.tf \u548c prod\/modules.tf \u6587\u4ef6\u4e2d\u3002\u8fd9\u91cc\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u65b0\u7684 modules \u8bed\u6cd5\u3002<\/p>\n<pre class=\"post-pre\"><code>module \"s3\" {\r\n  source = \"..\/modules\/s3\"  # \u3053\u3053\u3067\u8aad\u307f\u8fbc\u3080\u30d1\u30b9\u3092\u6307\u5b9a\r\n\r\n  env = \"${var.env}\"\r\n}\r\n\r\nvariable \"env\" {\r\n  default = \"dev\"  # prod \u306e\u307b\u3046\u306b\u306f prod \u3068\u66f8\u3044\u3066\u304f\u3060\u3055\u3044\r\n}\r\n<\/code><\/pre>\n<p>\u6700\u540e\uff0c\u6211\u4eec\u5c06\u4e3adev\/variable.tf\u548cprod\/variable.tf\u6587\u4ef6\u7f16\u5199\u5173\u4e8eAWS\u64cd\u4f5c\u7684\u8bbe\u7f6e\u503c\u7b49\u5185\u5bb9\u3002<\/p>\n<pre class=\"post-pre\"><code>provider \"aws\" {\r\n  region = \"${var.region}\"\r\n  access_key = \"${var.access_key}\"\r\n  secret_key = \"${var.secret_key}\"\r\n}\r\n\r\nvariable \"access_key\" {}\r\nvariable \"secret_key\" {}\r\nvariable \"region\" {\r\n  default = \"ap-northeast-1\"\r\n}\r\n<\/code><\/pre>\n<p>\u8fd9\u6837\u5c31\u51c6\u5907\u597d\u4e86\u3002\u5982\u679c\u4ecedev\u76ee\u5f55\u4e0b\u6267\u884c\uff0c\u53ef\u4ee5\u7ba1\u7406dev\u73af\u5883\u7684\u914d\u7f6e\uff1b\u5982\u679c\u4eceprod\u76ee\u5f55\u4e0b\u6267\u884c\uff0c\u53ef\u4ee5\u7ba1\u7406prod\u73af\u5883\u7684\u914d\u7f6e\u3002\u73b0\u5728\u6765\u521b\u5efadev\u73af\u5883\u6240\u9700\u7684\u8d44\u6e90\u5427\u3002\u524d\u5f80dev\u76ee\u5f55\uff0c\u6267\u884cterraform get\u5c06\u4f9d\u8d56\u6a21\u5757\u7684\u4ee3\u7801\u5bfc\u5165\uff0c\u5e76\u4e14\u57fa\u672c\u4e0a\u64cd\u4f5c\u4e0e\u4e4b\u524d\u76f8\u540c\uff0c\u9664\u4e86\u9700\u8981\u63d0\u524d\u8fdb\u884c\u5bfc\u5165\u5916\u3002<\/p>\n<pre class=\"post-pre\"><code>% cd dev\/                                                                                                     % terraform get                                                                                               \r\nGet: file:\/\/\/Users\/*******\/tutoterra\/sample\/modules\/s3\r\n% terraform plan                                                                                              Refreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but\r\nwill not be persisted to local or remote state storage.\r\n\r\n\r\nThe Terraform execution plan has been generated and is shown below.\r\nResources are shown in alphabetical order for quick scanning. Green resources\r\nwill be created (or destroyed and then created if an existing resource\r\nexists), yellow resources are being changed in-place, and red resources\r\nwill be destroyed. Cyan entries are data sources to be read.\r\n\r\nNote: You didn't specify an \"-out\" parameter to save this plan, so when\r\n\"apply\" is called, Terraform can't guarantee this is what will execute.\r\n\r\n+ module.s3.aws_s3_bucket.tutorial_s3\r\n    acceleration_status:           \"&lt;computed&gt;\"\r\n    acl:                           \"private\"\r\n    arn:                           \"&lt;computed&gt;\"\r\n    bucket:                        \"dev.53nigen.github.com.tutorial.s3\"\r\n    force_destroy:                 \"false\"\r\n    hosted_zone_id:                \"&lt;computed&gt;\"\r\n    policy:                        \"&lt;computed&gt;\"\r\n    region:                        \"&lt;computed&gt;\"\r\n    request_payer:                 \"&lt;computed&gt;\"\r\n    versioning.#:                  \"1\"\r\n    versioning.2972667452.enabled: \"false\"\r\n    website_domain:                \"&lt;computed&gt;\"\r\n    website_endpoint:              \"&lt;computed&gt;\"\r\n\r\n\r\nPlan: 1 to add, 0 to change, 0 to destroy.\r\n% terraform apply\r\nmodule.s3.aws_s3_bucket.tutorial_s3: Creating...\r\n  acceleration_status:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  acl:                           \"\" =&gt; \"private\"\r\n  arn:                           \"\" =&gt; \"&lt;computed&gt;\"\r\n  bucket:                        \"\" =&gt; \"dev.53nigen.github.com.tutorial.s3\"\r\n  force_destroy:                 \"\" =&gt; \"false\"\r\n  hosted_zone_id:                \"\" =&gt; \"&lt;computed&gt;\"\r\n  policy:                        \"\" =&gt; \"&lt;computed&gt;\"\r\n  region:                        \"\" =&gt; \"&lt;computed&gt;\"\r\n  request_payer:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  versioning.#:                  \"\" =&gt; \"1\"\r\n  versioning.2972667452.enabled: \"\" =&gt; \"false\"\r\n  website_domain:                \"\" =&gt; \"&lt;computed&gt;\"\r\n  website_endpoint:              \"\" =&gt; \"&lt;computed&gt;\"\r\nmodule.s3.aws_s3_bucket.tutorial_s3: Creation complete\r\n\r\nApply complete! Resources: 1 added, 0 changed, 0 destroyed.\r\n\r\nThe state of your infrastructure has been saved to the path\r\nbelow. This state is required to modify and destroy your\r\ninfrastructure, so keep it safe. To inspect the complete state\r\nuse the `terraform show` command.\r\n\r\nState path: terraform.tfstate\r\n<\/code><\/pre>\n<h3>5-2. \u5229\u7528\u6a21\u5757\u9002\u5e94\u591a\u4e2a\u9636\u6bb5\u7684\u6848\u4f8b<\/h3>\n<p>\u5982\u679c\u4f60\u60f3\u5229\u7528\u7c7b\u4f3c\u8fd9\u6837\u7684\u6a21\u5757\u529f\u80fd\u6765\u5bf9\u5f00\u53d1\u3001\u751f\u4ea7\u7b49\u591a\u4e2a\u9636\u6bb5\u8fdb\u884c\u90e8\u7f72\u6539\u9020\uff0c\u6ca1\u6709\u7279\u522b\u56fa\u5b9a\u7684\u76ee\u5f55\u7ed3\u6784\uff0c\u4f46\u5efa\u8bae\u53c2\u8003\u4ee5\u4e0b\u4f18\u79c0\u7684\u5f62\u5f0f\u6765\u8fdb\u884c\u64cd\u4f5c\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30aa\u30ec\u30aa\u30ecterraform\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u69cb\u6210\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">Terraform\u306b\u304a\u3051\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u69cb\u9020\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/ul>\n<h2>6. \u4f7f\u7528terraform\u7ba1\u7406\u73b0\u6709\u7684AWS\u8d44\u6e90<\/h2>\n<h3>6-1. \u5f15\u5165\u5730\u7403\u5316<\/h3>\n<p>terraform\u662f\u4e00\u79cd\u5de5\u5177\uff0c\u5b83\u53ef\u4ee5\u8bbf\u95ee\u73b0\u6709\u7684AWS\u8d44\u6e90\u5e76\u751f\u6210terraform\u4ee3\u7801\uff0c\u751f\u6210tfstate\u6587\u4ef6\u3002\u8981\u5b89\u88c5\u5b83\uff0c\u53ea\u9700\u5728Gemfile\u4e2d\u5199\u5165\u4ee5\u4e0b\u5185\u5bb9\uff0c\u7136\u540e\u8fd0\u884cbundle install\u5373\u53ef\u3002<\/p>\n<pre class=\"post-pre\"><code>source \"https:\/\/rubygems.org\"\r\n\r\ngem 'terraforming', '0.10.0'\r\n<\/code><\/pre>\n<h3>\u7528terraform\u7ba1\u7406\u73b0\u6709\u7684IAM\u7528\u6237\u3002<\/h3>\n<p>\u51e0\u4e4e\u6240\u6709\u62e5\u6709AWS\u5e10\u6237\u7684\u4eba\u90fd\u5df2\u7ecf\u62e5\u6709\u4e86IAM\u7528\u6237\u7b49\u8d44\u6e90\u3002\u56e0\u6b64\uff0c\u8ba9\u6211\u4eec\u9996\u5148\u4f7f\u7528terraform\u6765\u7ba1\u7406\u8fd9\u4e9b\u8d44\u6e90\u3002\u4f7f\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u53ef\u4ee5\u8f93\u51fa\u4e0e\u5f53\u524dIAM\u7528\u6237\u8d44\u6e90\u5bf9\u5e94\u7684HCL\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraforming iamu <span class=\"nt\">--profile<\/span> default\r\nresource <span class=\"s2\">\"aws_iam_user\"<\/span> <span class=\"s2\">\"gomi_ningen\"<\/span> <span class=\"o\">{<\/span>\r\n    name <span class=\"o\">=<\/span> <span class=\"s2\">\"gomi_ningen\"<\/span>\r\n    path <span class=\"o\">=<\/span> <span class=\"s2\">\"\/\"<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/code><\/pre>\n<p>\u8ba9\u6211\u4eec\u5c06\u8fd9\u4e2a\u5199\u5165\u6587\u4ef6\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code>resource \"aws_iam_user\" \"gomi_ningen\" {\r\n    name = \"gomi_ningen\"\r\n    path = \"\/\"\r\n}\r\n<\/code><\/pre>\n<p>\u5982\u679c\u4e0d\u5c06\u8fdc\u7a0b\u72b6\u6001\u540c\u6b65\u5230\u672c\u5730\u7684 .tfstate \u6587\u4ef6\u4e2d\uff0cterraform \u5c06\u4f1a\u5c1d\u8bd5\u521b\u5efa\u8d44\u6e90\u3002\u56e0\u6b64\uff0c\u8bf7\u6309\u7167\u4ee5\u4e0b\u65b9\u5f0f\u64cd\u4f5c\u3002<\/p>\n<p>\u901a\u8fc7\u4ee5\u4e0b\u547d\u4ee4\u8fdb\u884c\u571f\u5730\u6574\u5f62\uff1aiamu &#8211;tfstate &#8211;profile default &#8211;merge=.terraform\/terraform.tfstate<\/p>\n<p>\u5982\u679c\u901a\u8fc7\u68c0\u67e5\u8f93\u51fa\u6ca1\u6709\u95ee\u9898\u7684\u8bdd\uff0c\u60a8\u53ef\u4ee5\u5728\u8be5\u547d\u4ee4\u4e2d\u6dfb\u52a0 &#8220;&#8211;overwrite&#8221; \u9009\u9879\u6765\u8fdb\u884c\u53cd\u6620\u3002\u7136\u540e\u8fdb\u884c &#8220;terraform plan&#8221;\uff0c\u5982\u679c\u6ca1\u6709\u5dee\u5f02\uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u6b63\u5f0f\u5c06 IAM \u7528\u6237\u7684\u7ba1\u7406\u8f6c\u79fb\u5230 terraform\u3002<\/p>\n<p>\u5982\u679c\u5728\u6267\u884c&#8221;terraform plan&#8221;\u547d\u4ee4\u65f6\uff0c\u5982\u679c\u663e\u793a\u51fa\u5c06\u88ab\u9500\u6bc1\u7684\u8d44\u6e90\uff0c\u8bf7\u7279\u522b\u8c28\u614e\u64cd\u4f5c\uff0c\u56e0\u4e3a\u8fd9\u53ef\u80fd\u5bfc\u81f4\u73b0\u6709\u7684\u8d44\u6e90\u6216\u7cfb\u7edf\u88ab\u7834\u574f\u3002\u6b64\u5916\uff0c\u6709\u5173IAM\u7b56\u7565\u7684JSON\u6362\u884c\u4f4d\u7f6e\u548c\u7f29\u8fdb\u7b49\u5dee\u5f02\u5bb9\u6613\u51fa\u73b0\uff0c\u5f53\u56f0\u60d1\u65f6\u5efa\u8bae\u68c0\u67e5\u662f\u5426\u4e0e\u73b0\u6709\u7684\u7b56\u7565\u8bbe\u7f6e\u6709\u51b2\u7a81\u3002<\/p>\n<p>\u53ef\u4ee5\u8003\u8651\u4f7f\u7528 terraforming \u5c06\u73b0\u6709\u7684 AWS \u8d44\u6e90\u8fc1\u79fb\u5230 terraform \u4e2d\uff0c\u56e0\u4e3a terraforming \u9002\u7528\u4e8e\u591a\u6570\u5e38\u7528\u7684 AWS \u8d44\u6e90\u3002\u5728 v0.7.0 \u7248\u672c\u4e2d\uff0c terraforming \u652f\u6301\u4ee5\u4e0b\u529f\u80fd\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraforming help\r\nCommands:\r\n  terraforming asg             # AutoScaling Group\r\n  terraforming dbpg            # Database Parameter Group\r\n  terraforming dbsg            # Database Security Group\r\n  terraforming dbsn            # Database Subnet Group\r\n  terraforming ec2             # EC2\r\n  terraforming ecc             # ElastiCache Cluster\r\n  terraforming ecsn            # ElastiCache Subnet Group\r\n  terraforming eip             # EIP\r\n  terraforming elb             # ELB\r\n  terraforming help [COMMAND]  # Describe available commands or one specific command\r\n  terraforming iamg            # IAM Group\r\n  terraforming iamgm           # IAM Group Membership\r\n  terraforming iamgp           # IAM Group Policy\r\n  terraforming iamip           # IAM Instance Profile\r\n  terraforming iamp            # IAM Policy\r\n  terraforming iampa           # IAM Policy Attachment\r\n  terraforming iamr            # IAM Role\r\n  terraforming iamrp           # IAM Role Policy\r\n  terraforming iamu            # IAM User\r\n  terraforming iamup           # IAM User Policy\r\n  terraforming igw             # Internet Gateway\r\n  terraforming lc              # Launch Configuration\r\n  terraforming nacl            # Network ACL\r\n  terraforming nat             # NAT Gateway\r\n  terraforming nif             # Network Interface\r\n  terraforming r53r            # Route53 Record\r\n  terraforming r53z            # Route53 Hosted Zone\r\n  terraforming rds             # RDS\r\n  terraforming rs              # Redshift\r\n  terraforming rt              # Route Table\r\n  terraforming rta             # Route Table Association\r\n  terraforming s3              # S3\r\n  terraforming sg              # Security Group\r\n  terraforming sn              # Subnet\r\n  terraforming sqs             # SQS\r\n  terraforming vgw             # VPN Gateway\r\n  terraforming vpc             # VPC\r\n<\/code><\/pre>\n<h3>\u521b\u5efa\u4e00\u4e2a\u7528\u4e8e\u7ba1\u7406terraform\u4ee3\u7801\u7684\u5b58\u50a8\u5e93\u3002<\/h3>\n<p>\u5728\u672c\u884c\u7684\u7a0b\u5f0f\u78bc\u5b58\u5132\u5eab\u4e2d\u653e\u7f6e\u500b\u4ebaAWS\u914d\u7f6e\u6703\u5f15\u8d77\u9867\u616e\uff0c\u6240\u4ee5\u5efa\u8b70\u4e8b\u5148\u5275\u5efaCodeCommit\u5b58\u5132\u5eab\u3002<\/p>\n<pre class=\"post-pre\"><code># \u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306eAWS\u69cb\u6210\u3092\u7ba1\u7406\u3059\u308bterraform\u30b3\u30fc\u30c9\u3092\u914d\u7f6e\u3059\u308b\u30ec\u30dd\u30b8\u30c8\u30ea\r\nresource \"aws_codecommit_repository\" \"my-terraform\" {\r\n  repository_name = \"my-terraform\"\r\n  description = \"terrform\"\r\n}\r\n<\/code><\/pre>\n<p>\u53ef\u4ee5\u4f7f\u7528terraform\u6765\u9644\u52a0\u7b56\u7565\u5e76\u6ce8\u518c\u516c\u94a5\uff0c\u4ee5\u8bbf\u95ee\u5728code commit\u4e0a\u521b\u5efa\u7684\u5b58\u50a8\u5e93\u3002<\/p>\n<pre class=\"post-pre\"><code>#...\r\n\r\nresource \"aws_iam_policy_attachment\" \"my_codecommit_policy_attachment\" {\r\n  name       = \"my_terraform_codecommit_policy_attachment\"\r\n  policy_arn = \"arn:aws:iam::aws:policy\/AWSCodeCommitPowerUser\"\r\n  groups     = []\r\n  users      = [\"${aws_iam_user.gomi_ningen.name}\"]\r\n  roles      = []\r\n}\r\n\r\nresource \"aws_iam_user_ssh_key\" \"gomi_ningen\" {\r\n    username = \"${aws_iam_user.gomi_ningen.name}\"\r\n    encoding = \"PEM\"\r\n    public_key = &lt;&lt;EOF\r\n######################\r\n##### public_key #####\r\n######################\r\nEOF\r\n}\r\n\r\noutput \"aws_iam_user_ssh_key.gomi_ningen.ssh_key_id\"  {\r\n    value = \"${aws_iam_user_ssh_key.gomi_ningen.ssh_public_key_id}\"\r\n}\r\n<\/code><\/pre>\n<p>\u6211\u4f1a\u5728\u8fd9\u4e2a\u72b6\u6001\u4e0b\u5c1d\u8bd5\u6267\u884cterraform plan\u548cterraform apply\u3002<\/p>\n<pre class=\"post-pre\"><code>% terraform apply                                                                                                                                                     aws_s3_bucket.my_terraform_tfstate: Refreshing state... (ID: com.53ningen.aws.terraform.tfstates)\r\naws_codecommit_repository.my-terraform: Refreshing state... (ID: my-terraform)\r\n\r\n# \u4e2d\u7565\r\n\r\nOutputs:\r\n\r\naws_iam_user_ssh_key.gomi_ningen.ssh_key_id = XXXXXXXXXXXX\r\n<\/code><\/pre>\n<p>\u5f53\u6267\u884c\u6b64\u64cd\u4f5c\u540e\uff0c\u5c06\u4f1a\u8f93\u51fa\u7c7b\u4f3c\u4ee5\u4e0a\u6240\u793a\u7684 ssh_public_key_id\uff0c\u7136\u540e\u53ea\u9700\u5c06\u5176\u5e94\u7528\u5230 ~\/.ssh\/config \u6587\u4ef6\u4e2d\uff0c\u60a8\u5c31\u53ef\u4ee5\u901a\u8fc7\u672c\u5730\u8bbe\u5907\u4e0e\u521b\u5efa\u7684 code commit \u5b58\u50a8\u5e93\u8fdb\u884c\u901a\u4fe1\u3002<\/p>\n<pre class=\"post-pre\"><code>Host git-codecommit.*.amazonaws.com\r\n  User XXXXXXXXXXXX\r\n  IdentityFile ~\/.ssh\/id_rsa\r\n<\/code><\/pre>\n<h3>6-4. \u5730\u5f62\u6539\u9020\u7684\u5bfc\u5165<\/h3>\n<p>\u5f85\u5b9a<\/p>\n<h2>7. \u7b80\u5316\u6784\u6210\u7ba1\u7406\u65b9\u6cd5<\/h2>\n<h3>7-1. \u5982\u679c\u662f\u4e2a\u4eba\u5f00\u53d1\u7684\u60c5\u51b5<\/h3>\n<p>\u5982\u679c\u8981\u7ba1\u7406\u4e2a\u4eba\u7684AWS\u8d44\u6e90\uff0c\u5927\u81f4\u6709\u4ee5\u4e0b\u4e24\u79cd\u65b9\u6cd5\u3002<\/p>\n<p>.tfstate \u3054\u3068 git \u3067\u7ba1\u7406\u3057\u3066\u3001 code commit \u306b\u3076\u3061\u3053\u3080<\/p>\n<p>.tfstate \u306f S3 \u3067\u7ba1\u7406\u3001\u30b3\u30fc\u30c9\u306f code commit \u3067\u7ba1\u7406<\/p>\n<h3>7-2. \u5728\u56e2\u961f\u5f00\u53d1\u7684\u60c5\u51b5\u4e0b<\/h3>\n<p>.tfstate \u306f\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u4e0a\u306e\u7406\u7531\u304b\u3089 S3 \u3067\u7ba1\u7406\u3059\u308b\u3053\u3068\u304c\u671b\u307e\u3057\u3044<\/p>\n<p>.tfstate \u3084\u30a2\u30af\u30bb\u30b9\u30ad\u30fc\u306a\u3069\u3092\u542b\u3080\u3082\u306e\u3092\u30b3\u30df\u30c3\u30c8\u305b\u305a\u3001GitHub Enterprise, code commit, GitHub private repository \u306b push \u3059\u308b<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u8fd9\u7bc7\u6587\u7ae0\u7684\u5185\u5bb9\u9002\u7528\u4e8e terraform 0.9.0 \u7248\u672c\u4ee5\u4e0b\u3002\u867d\u7136\u5728 terraform 0.9.x \u7248\u672c\u4e2d [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-48680","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>\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c - 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\/\u4f7f\u7528terraform\u8fdb\u884caws\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c\" \/>\n<meta property=\"og:description\" content=\"\u8fd9\u7bc7\u6587\u7ae0\u7684\u5185\u5bb9\u9002\u7528\u4e8e terraform 0.9.0 \u7248\u672c\u4ee5\u4e0b\u3002\u867d\u7136\u5728 terraform 0.9.x \u7248\u672c\u4e2d [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528terraform\u8fdb\u884caws\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-11-21T05:59:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-04T10:27:52+00:00\" \/>\n<meta name=\"author\" content=\"\u6e05, \u5b87\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u6e05, \u5b87\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 \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\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/\",\"name\":\"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-11-21T05:59:04+00:00\",\"dateModified\":\"2024-05-04T10:27:52+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/1a6ecd3d914d22a5ac32791ffc1fbd8e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c\"}]},{\"@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\/1a6ecd3d914d22a5ac32791ffc1fbd8e\",\"name\":\"\u6e05, \u5b87\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g\",\"caption\":\"\u6e05, \u5b87\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/qingyu\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c - 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\/\u4f7f\u7528terraform\u8fdb\u884caws\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c","og_description":"\u8fd9\u7bc7\u6587\u7ae0\u7684\u5185\u5bb9\u9002\u7528\u4e8e terraform 0.9.0 \u7248\u672c\u4ee5\u4e0b\u3002\u867d\u7136\u5728 terraform 0.9.x \u7248\u672c\u4e2d [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528terraform\u8fdb\u884caws\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-11-21T05:59:04+00:00","article_modified_time":"2024-05-04T10:27:52+00:00","author":"\u6e05, \u5b87","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u6e05, \u5b87","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"12 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/","name":"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-11-21T05:59:04+00:00","dateModified":"2024-05-04T10:27:52+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/1a6ecd3d914d22a5ac32791ffc1fbd8e"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u4f7f\u7528Terraform\u8fdb\u884cAWS\u914d\u7f6e\u7ba1\u7406\u7684\u5b9e\u6218\u64cd\u4f5c"}]},{"@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\/1a6ecd3d914d22a5ac32791ffc1fbd8e","name":"\u6e05, \u5b87","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g","caption":"\u6e05, \u5b87"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/qingyu\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8terraform%e8%bf%9b%e8%a1%8caws%e9%85%8d%e7%bd%ae%e7%ae%a1%e7%90%86%e7%9a%84%e5%ae%9e%e6%88%98%e6%93%8d%e4%bd%9c%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\/48680","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\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=48680"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48680\/revisions"}],"predecessor-version":[{"id":99963,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48680\/revisions\/99963"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=48680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=48680"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=48680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}