{"id":2267,"date":"2025-03-24T08:47:50","date_gmt":"2025-03-23T23:47:50","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=2267"},"modified":"2025-03-24T08:48:14","modified_gmt":"2025-03-23T23:48:14","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91terraform%e3%81%a7aws%e3%82%a4%e3%83%b3%e3%83%95%e3%83%a9%e6%a7%8b%e7%af%89%e3%82%92%e5%ae%8c%e5%85%a8%e8%87%aa%e5%8b%95%e5%8c%96%ef%bc%81%e5%88%9d","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=2267","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011Terraform\u3067AWS\u30a4\u30f3\u30d5\u30e9\u69cb\u7bc9\u3092\u5b8c\u5168\u81ea\u52d5\u5316\uff01\u521d\u5fc3\u8005\u304b\u3089\u5b9f\u8df5\u8005\u307e\u3067\u4f7f\u3048\u308b7\u3064\u306e\u5fc5\u9808\u30c6\u30af\u30cb\u30c3\u30af"},"content":{"rendered":"\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">Terraform\u3092\u4f7f\u3063\u305fAWS\u74b0\u5883\u69cb\u7bc9\u306e\u57fa\u790e\u77e5\u8b58<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">Terraform\u3068AWS\u306e\u76f8\u6027\u304c\u629c\u7fa4\u306a3\u3064\u306e\u7406\u7531<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-2\">Terraform\u3092\u4f7f\u3063\u305fAWS\u74b0\u5883\u69cb\u7bc9\u306e\u5168\u4f53\u50cf<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-3\">Terraform\u306e\u74b0\u5883\u69cb\u7bc9\u304b\u3089AWS\u9023\u643a\u307e\u3067<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-4\">Terraform CLI\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3068\u521d\u671f\u8a2d\u5b9a\u306e\u624b\u9806<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-5\">AWS\u8a8d\u8a3c\u60c5\u5831\u306e\u8a2d\u5b9a\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-6\">\u5b9f\u8df5\uff01\u57fa\u672c\u7684\u306aAWS\u30ea\u30bd\u30fc\u30b9\u306e\u4f5c\u6210<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-7\">VPC\u3068\u30b5\u30d6\u30cd\u30c3\u30c8\u306e\u69cb\u7bc9\u4f8b<\/a>      <\/li>      <li>        <a href=\"#i-8\">EC2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u4f5c\u6210\u3068\u8a2d\u5b9a\u7ba1\u7406<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-9\">S3\u30d0\u30b1\u30c3\u30c8\u3068IAM\u30ed\u30fc\u30eb\u306e\u5b9a\u7fa9\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-10\">\u5b9f\u52d9\u3067\u4f7f\u3048\u308bTerraform\u904b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-11\">\u5909\u6570\u7ba1\u7406\u3068\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u306e\u6d3b\u7528\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-12\">\u30e2\u30b8\u30e5\u30fc\u30eb\u5316\u30b3\u30fc\u30c9\u306b\u3088\u308b\u518d\u5229\u7528\u6027\u5411\u4e0a<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-13\">\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-14\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u30b3\u30b9\u30c8\u6700\u9069\u5316\u306e\u5b9f\u88c5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-15\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b0\u30eb\u30fc\u30d7\u3068NACL\u306e\u8a2d\u5b9a\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-16\">\u30bf\u30b0\u4ed8\u3051\u306b\u3088\u308b\u30b3\u30b9\u30c8\u7ba1\u7406\u306e\u81ea\u52d5\u5316<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-17\">\u30c1\u30fc\u30e0\u958b\u767a\u306e\u305f\u3081\u306eTerraform\u904b\u7528\u30ac\u30a4\u30c9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-18\">Git\u3068CICD\u9023\u643a\u306b\u3088\u308b\u30a4\u30f3\u30d5\u30e9\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u7ba1\u7406<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-19\">\u30c1\u30fc\u30e0\u3067\u306e\u627f\u8a8d\u30d5\u30ed\u30fc\u3068\u5909\u66f4\u7ba1\u7406\u306e\u5b9f\u88c5<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-20\">\u3088\u304f\u3042\u308b\u30c8\u30e9\u30d6\u30eb\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-21\">\u30b9\u30c6\u30fc\u30c8\u554f\u984c\u306e\u9632\u6b62\u3068\u89e3\u6c7a\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-22\">\u4f9d\u5b58\u95a2\u4fc2\u30a8\u30e9\u30fc\u3078\u306e\u5bfe\u51e6\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">Terraform\u3092\u4f7f\u3063\u305fAWS\u74b0\u5883\u69cb\u7bc9\u306e\u57fa\u790e\u77e5\u8b58<\/h2>\n\n\n\n<p>\u30af\u30e9\u30a6\u30c9\u30a4\u30f3\u30d5\u30e9\u306e\u69cb\u7bc9\u3068\u7ba1\u7406\u3092\u81ea\u52d5\u5316\u3059\u308b\u4e0a\u3067\u3001Terraform\u3068AWS\u306e\u7d44\u307f\u5408\u308f\u305b\u306f\u975e\u5e38\u306b\u5f37\u529b\u306a\u30bd\u30ea\u30e5\u30fc\u30b7\u30e7\u30f3\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u3053\u306e\u7ae0\u3067\u306f\u3001\u306a\u305c\u3053\u306e\u7d44\u307f\u5408\u308f\u305b\u304c\u512a\u308c\u3066\u3044\u308b\u306e\u304b\u3001\u305d\u3057\u3066\u5b9f\u969b\u306e\u74b0\u5883\u69cb\u7bc9\u306b\u304a\u3044\u3066\u3069\u306e\u3088\u3046\u306a\u5168\u4f53\u50cf\u3068\u306a\u308b\u306e\u304b\u3092\u8a73\u3057\u304f\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">Terraform\u3068AWS\u306e\u76f8\u6027\u304c\u629c\u7fa4\u306a3\u3064\u306e\u7406\u7531<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5ba3\u8a00\u7684\u306a\u30a4\u30f3\u30d5\u30e9\u5b9a\u7fa9<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AWS\u306e\u30ea\u30bd\u30fc\u30b9\u3092HCL\uff08HashiCorp Configuration Language\uff09\u3067\u7c21\u6f54\u306b\u8a18\u8ff0\u53ef\u80fd<\/li>\n\n\n\n<li>\u30a4\u30f3\u30d5\u30e9\u306e\u671b\u307e\u3057\u3044\u72b6\u614b\u3092\u5ba3\u8a00\u3059\u308b\u3060\u3051\u3067\u3001Terraform\u304c\u5fc5\u8981\u306a\u5909\u66f4\u3092\u81ea\u52d5\u7684\u306b\u5224\u65ad<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u3068\u3057\u3066\u30d0\u30fc\u30b8\u30e7\u30f3\u7ba1\u7406\u304c\u53ef\u80fd\u3067\u3001\u30a4\u30f3\u30d5\u30e9\u306e\u5909\u66f4\u5c65\u6b74\u3092\u8ffd\u8de1\u53ef\u80fd<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8c4a\u5bcc\u306aAWS\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u30b5\u30dd\u30fc\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AWS\u516c\u5f0f\u304c\u63d0\u4f9b\u3059\u308b\u5305\u62ec\u7684\u306aTerraform\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc<\/li>\n\n\n\n<li>\u65b0\u3057\u3044AWS\u30b5\u30fc\u30d3\u30b9\u3078\u306e\u8fc5\u901f\u306a\u5bfe\u5fdc<\/li>\n\n\n\n<li>\u8a73\u7d30\u306a\u8a2d\u5b9a\u30aa\u30d7\u30b7\u30e7\u30f3\u3068\u8c4a\u5bcc\u306a\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5f37\u529b\u306a\u4f9d\u5b58\u95a2\u4fc2\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AWS\u30ea\u30bd\u30fc\u30b9\u9593\u306e\u8907\u96d1\u306a\u4f9d\u5b58\u95a2\u4fc2\u3092\u81ea\u52d5\u7684\u306b\u89e3\u6c7a<\/li>\n\n\n\n<li>\u4e26\u5217\u3067\u306e\u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\u306b\u3088\u308b\u9ad8\u901f\u306a\u30c7\u30d7\u30ed\u30a4<\/li>\n\n\n\n<li>\u5b89\u5168\u306a\u524a\u9664\u9806\u5e8f\u306e\u81ea\u52d5\u6c7a\u5b9a<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">Terraform\u3092\u4f7f\u3063\u305fAWS\u74b0\u5883\u69cb\u7bc9\u306e\u5168\u4f53\u50cf<\/h3>\n\n\n\n<p><strong>1. \u57fa\u672c\u7684\u306a\u30ef\u30fc\u30af\u30d5\u30ed\u30fc<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u8a2d\u5b9a\nprovider \"aws\" {\n  region = \"ap-northeast-1\"\n}\n\n# \u57fa\u672c\u7684\u306aVPC\u306e\u5b9a\u7fa9\nresource \"aws_vpc\" \"main\" {\n  cidr_block = \"10.0.0.0\/16\"\n\n  tags = {\n    Name = \"main-vpc\"\n  }\n}<\/pre>\n\n\n\n<p><strong>2. \u4e3b\u8981\u306a\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>terraform init<\/code>: \u521d\u671f\u5316\u3068\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9<\/li>\n\n\n\n<li><code>terraform plan<\/code>: \u5b9f\u884c\u8a08\u753b\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li><code>terraform apply<\/code>: \u30a4\u30f3\u30d5\u30e9\u306e\u4f5c\u6210\u30fb\u66f4\u65b0<\/li>\n\n\n\n<li><code>terraform destroy<\/code>: \u30ea\u30bd\u30fc\u30b9\u306e\u524a\u9664<\/li>\n<\/ul>\n\n\n\n<p><strong>3. \u91cd\u8981\u306a\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>main.tf<\/code>: \u30e1\u30a4\u30f3\u306e\u30ea\u30bd\u30fc\u30b9\u5b9a\u7fa9<\/li>\n\n\n\n<li><code>variables.tf<\/code>: \u5909\u6570\u5b9a\u7fa9<\/li>\n\n\n\n<li><code>outputs.tf<\/code>: \u51fa\u529b\u5024\u306e\u5b9a\u7fa9<\/li>\n\n\n\n<li><code>terraform.tfstate<\/code>: \u72b6\u614b\u7ba1\u7406\u30d5\u30a1\u30a4\u30eb<\/li>\n<\/ul>\n\n\n\n<p><strong>\u30d7\u30e9\u30af\u30c6\u30a3\u30ab\u30eb\u306a\u30d2\u30f3\u30c8<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u74b0\u5883\u3054\u3068\u306b\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u3092\u5206\u96e2<\/li>\n\n\n\n<li>\u30ea\u30e2\u30fc\u30c8\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u3067\u30c1\u30fc\u30e0\u958b\u767a\u306b\u5bfe\u5fdc<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u6d3b\u7528\u3057\u3066\u65e2\u5b58\u30ea\u30bd\u30fc\u30b9\u3092\u53c2\u7167<\/li>\n<\/ol>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306a\u4f53\u7cfb\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u306b\u3088\u308a\u3001AWS\u30a4\u30f3\u30d5\u30e9\u306e\u7ba1\u7406\u304c\u683c\u6bb5\u306b\u52b9\u7387\u5316\u3055\u308c\u3001\u4eba\u7684\u30df\u30b9\u3082\u5927\u5e45\u306b\u6e1b\u5c11\u3057\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u5b9f\u969b\u306e\u74b0\u5883\u69cb\u7bc9\u624b\u9806\u306b\u5165\u3063\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-3\">Terraform\u306e\u74b0\u5883\u69cb\u7bc9\u304b\u3089AWS\u9023\u643a\u307e\u3067<\/h2>\n\n\n\n<p>\u52b9\u7387\u7684\u306a\u30a4\u30f3\u30d5\u30e9\u69cb\u7bc9\u3092\u59cb\u3081\u308b\u305f\u3081\u306e\u7b2c\u4e00\u6b69\u3068\u3057\u3066\u3001Terraform\u3068AWS\u306e\u9023\u643a\u8a2d\u5b9a\u3092\u6b63\u3057\u304f\u884c\u3046\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002\u3053\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u8a8d\u8a3c\u8a2d\u5b9a\u307e\u3067\u3001\u5b9f\u8df5\u7684\u306a\u624b\u9806\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-4\">Terraform CLI\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3068\u521d\u671f\u8a2d\u5b9a\u306e\u624b\u9806<\/h3>\n\n\n\n<p><strong>1. Terraform\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/strong><\/p>\n\n\n\n<p>\u5404OS\u5411\u3051\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u624b\u9806\u3092\u7d39\u4ecb\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<p><strong>macOS\uff08Homebrew\u4f7f\u7528\uff09<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Homebrew\u3067\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\nbrew install terraform\n\n# \u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d\nterraform version<\/pre>\n\n\n\n<p><strong>Ubuntu\/Debian<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u5fc5\u8981\u306a\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\nsudo apt-get update &amp;&amp; sudo apt-get install -y gnupg software-properties-common\n\n# HashiCorp GPG\u30ad\u30fc\u306e\u8ffd\u52a0\nwget -O- https:\/\/apt.releases.hashicorp.com\/gpg | gpg --dearmor | sudo tee \/usr\/share\/keyrings\/hashicorp-archive-keyring.gpg\n\n# \u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u8ffd\u52a0\necho \"deb [signed-by=\/usr\/share\/keyrings\/hashicorp-archive-keyring.gpg] https:\/\/apt.releases.hashicorp.com $(lsb_release -cs) main\" | sudo tee \/etc\/apt\/sources.list.d\/hashicorp.list\n\n# Terraform\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\nsudo apt-get update &amp;&amp; sudo apt-get install terraform<\/pre>\n\n\n\n<p><strong>Windows\uff08Chocolatey\u4f7f\u7528\uff09<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Chocolatey\u3067\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\nchoco install terraform\n\n# \u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d\nterraform --version<\/pre>\n\n\n\n<p><strong>2. \u521d\u671f\u8a2d\u5b9a\u3068\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u69cb\u6210<\/strong><\/p>\n\n\n\n<p>\u57fa\u672c\u7684\u306a\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u69cb\u9020\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">my-terraform-project\/\n\u251c\u2500\u2500 main.tf          # \u30e1\u30a4\u30f3\u306eTerraform\u8a2d\u5b9a\n\u251c\u2500\u2500 variables.tf     # \u5909\u6570\u5b9a\u7fa9\n\u251c\u2500\u2500 outputs.tf       # \u51fa\u529b\u5b9a\u7fa9\n\u251c\u2500\u2500 terraform.tfvars # \u74b0\u5883\u56fa\u6709\u306e\u5909\u6570\u5024\n\u2514\u2500\u2500 .gitignore      # Git\u306e\u9664\u5916\u8a2d\u5b9a<\/pre>\n\n\n\n<p><code>.gitignore<\/code>\u306e\u63a8\u5968\u8a2d\u5b9a\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ed\u30fc\u30ab\u30eb\u72b6\u614b\u30d5\u30a1\u30a4\u30eb\n*.tfstate\n*.tfstate.*\n\n# \u5909\u6570\u30d5\u30a1\u30a4\u30eb\uff08\u6a5f\u5bc6\u60c5\u5831\u3092\u542b\u3080\u53ef\u80fd\u6027\u3042\u308a\uff09\n*.tfvars\n\n# CLI\u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\n.terraformrc\nterraform.rc\n\n# \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\n.terraform\/<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">AWS\u8a8d\u8a3c\u60c5\u5831\u306e\u8a2d\u5b9a\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<p><strong>1. AWS\u8a8d\u8a3c\u60c5\u5831\u306e\u8a2d\u5b9a\u65b9\u6cd5<\/strong><\/p>\n\n\n\n<p>AWS CLI\u3092\u4f7f\u7528\u3057\u305f\u8a8d\u8a3c\u60c5\u5831\u306e\u8a2d\u5b9a\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># AWS CLI\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\uff08\u307e\u3060\u306e\u5834\u5408\uff09\npip install awscli\n\n# \u8a8d\u8a3c\u60c5\u5831\u306e\u8a2d\u5b9a\naws configure<\/pre>\n\n\n\n<p>\u307e\u305f\u306f\u3001\u74b0\u5883\u5909\u6570\u3092\u4f7f\u7528\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">export AWS_ACCESS_KEY_ID=\"your_access_key\"\nexport AWS_SECRET_ACCESS_KEY=\"your_secret_key\"\nexport AWS_DEFAULT_REGION=\"ap-northeast-1\"<\/pre>\n\n\n\n<p><strong>2. \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/strong><\/p>\n\n\n\n<p>\u8a8d\u8a3c\u60c5\u5831\u7ba1\u7406\u306e\u63a8\u5968\u30a2\u30d7\u30ed\u30fc\u30c1\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>IAM\u30ed\u30fc\u30eb\u306e\u4f7f\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># EC2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u5b9a\u7fa9\u4f8b\nresource \"aws_iam_role\" \"terraform_role\" {\n  name = \"terraform-execution-role\"\n\n  assume_role_policy = jsonencode({\n    Version = \"2012-10-17\"\n    Statement = [\n      {\n        Action = \"sts:AssumeRole\"\n        Effect = \"Allow\"\n        Principal = {\n          Service = \"ec2.amazonaws.com\"\n        }\n      }\n    ]\n  })\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30af\u30ec\u30c7\u30f3\u30b7\u30e3\u30eb\u306e\u6697\u53f7\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># KMS\u30ad\u30fc\u306e\u4f7f\u7528\u4f8b\nresource \"aws_kms_key\" \"terraform_key\" {\n  description = \"KMS key for Terraform secrets\"\n  enable_key_rotation = true\n}\n\n# S3\u30d0\u30b1\u30c3\u30c8\u306e\u6697\u53f7\u5316\u8a2d\u5b9a\nresource \"aws_s3_bucket\" \"terraform_state\" {\n  bucket = \"my-terraform-state-bucket\"\n\n  server_side_encryption_configuration {\n    rule {\n      apply_server_side_encryption_by_default {\n        kms_master_key_id = aws_kms_key.terraform_key.arn\n        sse_algorithm     = \"aws:kms\"\n      }\n    }\n  }\n}<\/pre>\n\n\n\n<p><strong>3. \u74b0\u5883\u5206\u96e2\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u74b0\u5883\u5225\u306e\u8a2d\u5b9a\u4f8b\nprovider \"aws\" {\n  region = var.aws_region\n\n  assume_role {\n    role_arn = var.environment == \"production\" ? var.prod_role_arn : var.dev_role_arn\n  }\n\n  default_tags {\n    tags = {\n      Environment = var.environment\n      ManagedBy   = \"Terraform\"\n      Project     = var.project_name\n    }\n  }\n}<\/pre>\n\n\n\n<p>\u4ee5\u4e0a\u306e\u8a2d\u5b9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3067\u8a2d\u5b9a\u306e\u691c\u8a3c\u3092\u884c\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u521d\u671f\u5316\nterraform init\n\n# \u8a2d\u5b9a\u306e\u691c\u8a3c\nterraform validate\n\n# \u5b9f\u884c\u8a08\u753b\u306e\u78ba\u8a8d\nterraform plan<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u57fa\u672c\u8a2d\u5b9a\u3092\u9069\u5207\u306b\u884c\u3046\u3053\u3068\u3067\u3001\u5b89\u5168\u3067\u52b9\u7387\u7684\u306aTerraform\u74b0\u5883\u304c\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u5b9f\u969b\u306eAWS\u30ea\u30bd\u30fc\u30b9\u306e\u4f5c\u6210\u306b\u9032\u3093\u3067\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-6\">\u5b9f\u8df5\uff01\u57fa\u672c\u7684\u306aAWS\u30ea\u30bd\u30fc\u30b9\u306e\u4f5c\u6210<\/h2>\n\n\n\n<p>\u3053\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001Terraform\u3092\u4f7f\u7528\u3057\u3066\u57fa\u672c\u7684\u306aAWS\u30ea\u30bd\u30fc\u30b9\u3092\u4f5c\u6210\u3059\u308b\u5177\u4f53\u7684\u306a\u65b9\u6cd5\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002\u5b9f\u52d9\u3067\u3088\u304f\u4f7f\u7528\u3055\u308c\u308b\u4e3b\u8981\u306a\u30ea\u30bd\u30fc\u30b9\u306e\u69cb\u7bc9\u4f8b\u3092\u901a\u3058\u3066\u3001\u5b9f\u8df5\u7684\u306a\u30a4\u30f3\u30d5\u30e9\u69cb\u7bc9\u306e\u30b9\u30ad\u30eb\u3092\u8eab\u306b\u3064\u3051\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">VPC\u3068\u30b5\u30d6\u30cd\u30c3\u30c8\u306e\u69cb\u7bc9\u4f8b<\/h3>\n\n\n\n<p>\u307e\u305a\u3001\u9069\u5207\u306a\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u74b0\u5883\u3092\u69cb\u7bc9\u3059\u308b\u305f\u3081\u306eVPC\u3068\u30b5\u30d6\u30cd\u30c3\u30c8\u306e\u4f5c\u6210\u65b9\u6cd5\u3092\u898b\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># VPC\u306e\u4f5c\u6210\nresource \"aws_vpc\" \"main\" {\n  cidr_block           = \"10.0.0.0\/16\"\n  enable_dns_hostnames = true\n  enable_dns_support   = true\n\n  tags = {\n    Name = \"main-vpc\"\n    Environment = var.environment\n  }\n}\n\n# \u30d1\u30d6\u30ea\u30c3\u30af\u30b5\u30d6\u30cd\u30c3\u30c8\u306e\u4f5c\u6210\nresource \"aws_subnet\" \"public\" {\n  count             = length(var.availability_zones)\n  vpc_id            = aws_vpc.main.id\n  cidr_block        = \"10.0.${count.index + 1}.0\/24\"\n  availability_zone = var.availability_zones[count.index]\n\n  map_public_ip_on_launch = true\n\n  tags = {\n    Name = \"public-subnet-${count.index + 1}\"\n    Type = \"Public\"\n  }\n}\n\n# \u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u30b5\u30d6\u30cd\u30c3\u30c8\u306e\u4f5c\u6210\nresource \"aws_subnet\" \"private\" {\n  count             = length(var.availability_zones)\n  vpc_id            = aws_vpc.main.id\n  cidr_block        = \"10.0.${count.index + 10}.0\/24\"\n  availability_zone = var.availability_zones[count.index]\n\n  tags = {\n    Name = \"private-subnet-${count.index + 1}\"\n    Type = \"Private\"\n  }\n}\n\n# \u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u4f5c\u6210\nresource \"aws_internet_gateway\" \"main\" {\n  vpc_id = aws_vpc.main.id\n\n  tags = {\n    Name = \"main-igw\"\n  }\n}\n\n# NAT\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u7528\u306eElastic IP\u306e\u4f5c\u6210\nresource \"aws_eip\" \"nat\" {\n  count = length(var.availability_zones)\n  vpc   = true\n\n  tags = {\n    Name = \"nat-eip-${count.index + 1}\"\n  }\n}\n\n# NAT\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u4f5c\u6210\nresource \"aws_nat_gateway\" \"main\" {\n  count         = length(var.availability_zones)\n  allocation_id = aws_eip.nat[count.index].id\n  subnet_id     = aws_subnet.public[count.index].id\n\n  tags = {\n    Name = \"nat-gateway-${count.index + 1}\"\n  }\n}\n\n# \u30eb\u30fc\u30c8\u30c6\u30fc\u30d6\u30eb\u306e\u8a2d\u5b9a\nresource \"aws_route_table\" \"public\" {\n  vpc_id = aws_vpc.main.id\n\n  route {\n    cidr_block = \"0.0.0.0\/0\"\n    gateway_id = aws_internet_gateway.main.id\n  }\n\n  tags = {\n    Name = \"public-route-table\"\n  }\n}\n\nresource \"aws_route_table\" \"private\" {\n  count  = length(var.availability_zones)\n  vpc_id = aws_vpc.main.id\n\n  route {\n    cidr_block     = \"0.0.0.0\/0\"\n    nat_gateway_id = aws_nat_gateway.main[count.index].id\n  }\n\n  tags = {\n    Name = \"private-route-table-${count.index + 1}\"\n  }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-8\">EC2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u4f5c\u6210\u3068\u8a2d\u5b9a\u7ba1\u7406<\/h3>\n\n\n\n<p>\u6b21\u306b\u3001EC2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u4f5c\u6210\u3068\u95a2\u9023\u30ea\u30bd\u30fc\u30b9\u306e\u8a2d\u5b9a\u65b9\u6cd5\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ad\u30fc\u30da\u30a2\u306e\u4f5c\u6210\nresource \"aws_key_pair\" \"main\" {\n  key_name   = \"terraform-key\"\n  public_key = file(\"~\/.ssh\/terraform.pub\")\n}\n\n# \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b0\u30eb\u30fc\u30d7\u306e\u4f5c\u6210\nresource \"aws_security_group\" \"web\" {\n  name        = \"web-security-group\"\n  description = \"Security group for web servers\"\n  vpc_id      = aws_vpc.main.id\n\n  ingress {\n    from_port   = 80\n    to_port     = 80\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  ingress {\n    from_port   = 443\n    to_port     = 443\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  ingress {\n    from_port   = 22\n    to_port     = 22\n    protocol    = \"tcp\"\n    cidr_blocks = [var.admin_ip]\n  }\n\n  egress {\n    from_port   = 0\n    to_port     = 0\n    protocol    = \"-1\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  tags = {\n    Name = \"web-sg\"\n  }\n}\n\n# EC2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u4f5c\u6210\nresource \"aws_instance\" \"web\" {\n  count = var.instance_count\n\n  ami           = var.ami_id\n  instance_type = var.instance_type\n  subnet_id     = aws_subnet.public[count.index % length(aws_subnet.public)].id\n\n  key_name               = aws_key_pair.main.key_name\n  vpc_security_group_ids = [aws_security_group.web.id]\n\n  root_block_device {\n    volume_size = 20\n    volume_type = \"gp3\"\n  }\n\n  user_data = &lt;&lt;-EOF\n              #!\/bin\/bash\n              yum update -y\n              yum install -y httpd\n              systemctl start httpd\n              systemctl enable httpd\n              EOF\n\n  tags = {\n    Name = \"web-server-${count.index + 1}\"\n    Role = \"WebServer\"\n  }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">S3\u30d0\u30b1\u30c3\u30c8\u3068IAM\u30ed\u30fc\u30eb\u306e\u5b9a\u7fa9\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u6700\u5f8c\u306b\u3001S3\u30d0\u30b1\u30c3\u30c8\u306e\u4f5c\u6210\u3068IAM\u30ed\u30fc\u30eb\u306e\u8a2d\u5b9a\u65b9\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># S3\u30d0\u30b1\u30c3\u30c8\u306e\u4f5c\u6210\nresource \"aws_s3_bucket\" \"app_data\" {\n  bucket = \"${var.project_name}-${var.environment}-data\"\n\n  tags = {\n    Name        = \"${var.project_name}-data\"\n    Environment = var.environment\n  }\n}\n\n# \u30d0\u30b1\u30c3\u30c8\u306e\u6697\u53f7\u5316\u8a2d\u5b9a\nresource \"aws_s3_bucket_server_side_encryption_configuration\" \"app_data\" {\n  bucket = aws_s3_bucket.app_data.id\n\n  rule {\n    apply_server_side_encryption_by_default {\n      sse_algorithm = \"AES256\"\n    }\n  }\n}\n\n# \u30d0\u30b1\u30c3\u30c8\u306e\u30d0\u30fc\u30b8\u30e7\u30cb\u30f3\u30b0\u8a2d\u5b9a\nresource \"aws_s3_bucket_versioning\" \"app_data\" {\n  bucket = aws_s3_bucket.app_data.id\n  versioning_configuration {\n    status = \"Enabled\"\n  }\n}\n\n# IAM\u30ed\u30fc\u30eb\u306e\u4f5c\u6210\nresource \"aws_iam_role\" \"ec2_s3_access\" {\n  name = \"ec2-s3-access-role\"\n\n  assume_role_policy = jsonencode({\n    Version = \"2012-10-17\"\n    Statement = [\n      {\n        Action = \"sts:AssumeRole\"\n        Effect = \"Allow\"\n        Principal = {\n          Service = \"ec2.amazonaws.com\"\n        }\n      }\n    ]\n  })\n}\n\n# IAM\u30dd\u30ea\u30b7\u30fc\u306e\u4f5c\u6210\nresource \"aws_iam_role_policy\" \"s3_access\" {\n  name = \"s3-access-policy\"\n  role = aws_iam_role.ec2_s3_access.id\n\n  policy = jsonencode({\n    Version = \"2012-10-17\"\n    Statement = [\n      {\n        Effect = \"Allow\"\n        Action = [\n          \"s3:GetObject\",\n          \"s3:PutObject\",\n          \"s3:ListBucket\"\n        ]\n        Resource = [\n          aws_s3_bucket.app_data.arn,\n          \"${aws_s3_bucket.app_data.arn}\/*\"\n        ]\n      }\n    ]\n  })\n}\n\n# \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210\nresource \"aws_iam_instance_profile\" \"ec2_s3_profile\" {\n  name = \"ec2-s3-profile\"\n  role = aws_iam_role.ec2_s3_access.name\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30ea\u30bd\u30fc\u30b9\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u30bb\u30ad\u30e5\u30a2\u3067\u53ef\u7528\u6027\u306e\u9ad8\u3044AWS\u74b0\u5883\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30ea\u30bd\u30fc\u30b9\u3092\u52b9\u7387\u7684\u306b\u7ba1\u7406\u30fb\u904b\u7528\u3059\u308b\u305f\u3081\u306e\u30c6\u30af\u30cb\u30c3\u30af\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-10\">\u5b9f\u52d9\u3067\u4f7f\u3048\u308bTerraform\u904b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/h2>\n\n\n\n<p>\u672c\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u5b9f\u52d9\u3067Terraform\u3092\u52b9\u7387\u7684\u306b\u904b\u7528\u3059\u308b\u305f\u3081\u306e\u91cd\u8981\u306a\u30c6\u30af\u30cb\u30c3\u30af\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002\u7279\u306b\u3001\u5909\u6570\u7ba1\u7406\u3001\u30e2\u30b8\u30e5\u30fc\u30eb\u5316\u3001\u305d\u3057\u3066\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u3068\u3044\u30463\u3064\u306e\u91cd\u8981\u306a\u5074\u9762\u306b\u7126\u70b9\u3092\u5f53\u3066\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-11\">\u5909\u6570\u7ba1\u7406\u3068\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u306e\u6d3b\u7528\u6cd5<\/h3>\n\n\n\n<p>\u52b9\u7387\u7684\u306a\u5909\u6570\u7ba1\u7406\u306f\u3001\u74b0\u5883\u9593\u306e\u8a2d\u5b9a\u306e\u4e00\u8cab\u6027\u3092\u4fdd\u3061\u3001\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u3092\u5411\u4e0a\u3055\u305b\u308b\u91cd\u8981\u306a\u8981\u7d20\u3067\u3059\u3002<\/p>\n\n\n\n<p><strong>1. \u5909\u6570\u5b9a\u7fa9\u306e\u69cb\u9020\u5316<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># variables.tf\nvariable \"environment\" {\n  description = \"\u74b0\u5883\u3092\u6307\u5b9a\uff08dev\/stg\/prod\uff09\"\n  type        = string\n  validation {\n    condition     = contains([\"dev\", \"stg\", \"prod\"], var.environment)\n    error_message = \"\u74b0\u5883\u306f'dev'\u3001'stg'\u3001'prod'\u306e\u3044\u305a\u308c\u304b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\"\n  }\n}\n\nvariable \"vpc_config\" {\n  description = \"VPC\u8a2d\u5b9a\"\n  type = object({\n    cidr_block = string\n    azs        = list(string)\n    subnets = object({\n      public  = list(string)\n      private = list(string)\n    })\n  })\n}\n\n# terraform.tfvars\nenvironment = \"dev\"\nvpc_config = {\n  cidr_block = \"10.0.0.0\/16\"\n  azs        = [\"ap-northeast-1a\", \"ap-northeast-1c\"]\n  subnets = {\n    public  = [\"10.0.1.0\/24\", \"10.0.2.0\/24\"]\n    private = [\"10.0.10.0\/24\", \"10.0.11.0\/24\"]\n  }\n}<\/pre>\n\n\n\n<p><strong>2. \u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u958b\u767a\u74b0\u5883\u7528\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u306e\u4f5c\u6210\u3068\u5207\u308a\u66ff\u3048\nterraform workspace new dev\nterraform workspace select dev\n\n# \u672c\u756a\u74b0\u5883\u7528\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u306e\u4f5c\u6210\u3068\u5207\u308a\u66ff\u3048\nterraform workspace new prod<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u306b\u57fa\u3065\u304f\u6761\u4ef6\u5206\u5c90\u306e\u4f8b\nlocals {\n  environment = terraform.workspace\n\n  instance_type = {\n    dev  = \"t3.micro\"\n    stg  = \"t3.small\"\n    prod = \"t3.medium\"\n  }\n\n  instance_count = {\n    dev  = 1\n    stg  = 2\n    prod = 3\n  }\n}\n\nresource \"aws_instance\" \"app\" {\n  count         = local.instance_count[local.environment]\n  instance_type = local.instance_type[local.environment]\n  # ... \u4ed6\u306e\u8a2d\u5b9a\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-12\">\u30e2\u30b8\u30e5\u30fc\u30eb\u5316\u30b3\u30fc\u30c9\u306b\u3088\u308b\u518d\u5229\u7528\u6027\u5411\u4e0a<\/h3>\n\n\n\n<p>\u30e2\u30b8\u30e5\u30fc\u30eb\u5316\u306f\u3001\u30b3\u30fc\u30c9\u306e\u518d\u5229\u7528\u6027\u3092\u9ad8\u3081\u3001\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u3092\u5411\u4e0a\u3055\u305b\u308b\u91cd\u8981\u306a\u624b\u6cd5\u3067\u3059\u3002<\/p>\n\n\n\n<p><strong>1. \u30e2\u30b8\u30e5\u30fc\u30eb\u69cb\u9020\u306e\u4f8b<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">terraform-aws-modules\/\n\u251c\u2500\u2500 vpc\/\n\u2502   \u251c\u2500\u2500 main.tf\n\u2502   \u251c\u2500\u2500 variables.tf\n\u2502   \u251c\u2500\u2500 outputs.tf\n\u2502   \u2514\u2500\u2500 README.md\n\u251c\u2500\u2500 ec2\/\n\u2502   \u251c\u2500\u2500 main.tf\n\u2502   \u251c\u2500\u2500 variables.tf\n\u2502   \u251c\u2500\u2500 outputs.tf\n\u2502   \u2514\u2500\u2500 README.md\n\u2514\u2500\u2500 rds\/\n    \u251c\u2500\u2500 main.tf\n    \u251c\u2500\u2500 variables.tf\n    \u251c\u2500\u2500 outputs.tf\n    \u2514\u2500\u2500 README.md<\/pre>\n\n\n\n<p><strong>2. VPC\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u5b9f\u88c5\u4f8b<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># modules\/vpc\/main.tf\nmodule \"vpc\" {\n  source = \".\/modules\/vpc\"\n\n  name                 = \"${var.project}-${var.environment}\"\n  cidr                 = var.vpc_cidr\n  azs                  = var.availability_zones\n  private_subnets      = var.private_subnet_cidrs\n  public_subnets       = var.public_subnet_cidrs\n  enable_nat_gateway   = true\n  single_nat_gateway   = var.environment != \"prod\"\n  enable_dns_hostnames = true\n\n  tags = {\n    Project     = var.project\n    Environment = var.environment\n    Terraform   = \"true\"\n  }\n}\n\n# \u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u4f7f\u7528\u4f8b\nmodule \"vpc\" {\n  source = \".\/modules\/vpc\"\n\n  project            = \"example\"\n  environment        = local.environment\n  vpc_cidr           = \"10.0.0.0\/16\"\n  availability_zones = [\"ap-northeast-1a\", \"ap-northeast-1c\"]\n\n  private_subnet_cidrs = [\"10.0.1.0\/24\", \"10.0.2.0\/24\"]\n  public_subnet_cidrs  = [\"10.0.101.0\/24\", \"10.0.102.0\/24\"]\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<p>Terraform\u306e\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u306f\u3001\u30c1\u30fc\u30e0\u958b\u767a\u306b\u304a\u3051\u308b\u91cd\u8981\u306a\u8981\u7d20\u3067\u3059\u3002<\/p>\n\n\n\n<p><strong>1. \u30ea\u30e2\u30fc\u30c8\u30b9\u30c6\u30fc\u30c8\u306e\u8a2d\u5b9a<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u8a2d\u5b9a\uff08S3 + DynamoDB\uff09\nterraform {\n  backend \"s3\" {\n    bucket         = \"terraform-state-bucket\"\n    key            = \"terraform.tfstate\"\n    region         = \"ap-northeast-1\"\n    encrypt        = true\n    dynamodb_table = \"terraform-state-lock\"\n  }\n}\n\n# \u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u7528\u306e\u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\nresource \"aws_s3_bucket\" \"terraform_state\" {\n  bucket = \"terraform-state-bucket\"\n\n  versioning {\n    enabled = true\n  }\n\n  server_side_encryption_configuration {\n    rule {\n      apply_server_side_encryption_by_default {\n        sse_algorithm = \"AES256\"\n      }\n    }\n  }\n}\n\nresource \"aws_dynamodb_table\" \"terraform_state_lock\" {\n  name           = \"terraform-state-lock\"\n  billing_mode   = \"PAY_PER_REQUEST\"\n  hash_key       = \"LockID\"\n\n  attribute {\n    name = \"LockID\"\n    type = \"S\"\n  }\n}<\/pre>\n\n\n\n<p><strong>2. \u30b9\u30c6\u30fc\u30c8\u306e\u5206\u5272\u7ba1\u7406<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u74b0\u5883\u3054\u3068\u306e\u30b9\u30c6\u30fc\u30c8\u5206\u5272\u4f8b\nterraform {\n  backend \"s3\" {\n    bucket = \"terraform-state-bucket\"\n    key    = \"${local.environment}\/terraform.tfstate\"\n    region = \"ap-northeast-1\"\n  }\n}\n\n# \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306b\u3088\u308b\u4ed6\u306e\u30b9\u30c6\u30fc\u30c8\u306e\u53c2\u7167\ndata \"terraform_remote_state\" \"vpc\" {\n  backend = \"s3\"\n  config = {\n    bucket = \"terraform-state-bucket\"\n    key    = \"${local.environment}\/vpc\/terraform.tfstate\"\n    region = \"ap-northeast-1\"\n  }\n}\n\n# \u53c2\u7167\u4f8b\nresource \"aws_instance\" \"app\" {\n  subnet_id = data.terraform_remote_state.vpc.outputs.private_subnet_ids[0]\n  # ... \u4ed6\u306e\u8a2d\u5b9a\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30c6\u30af\u30cb\u30c3\u30af\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u5b89\u5168\u306aTerraform\u904b\u7528\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u30b3\u30b9\u30c8\u6700\u9069\u5316\u306b\u3064\u3044\u3066\u8a73\u3057\u304f\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-14\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u30b3\u30b9\u30c8\u6700\u9069\u5316\u306e\u5b9f\u88c5<\/h2>\n\n\n\n<p>AWS\u30a4\u30f3\u30d5\u30e9\u306e\u904b\u7528\u306b\u304a\u3044\u3066\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u30b3\u30b9\u30c8\u7ba1\u7406\u306f\u6700\u3082\u91cd\u8981\u306a\u8981\u7d20\u306e\u4e00\u3064\u3067\u3059\u3002\u672c\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001Terraform\u3092\u4f7f\u7528\u3057\u3066\u3053\u308c\u3089\u3092\u52b9\u679c\u7684\u306b\u5b9f\u88c5\u3059\u308b\u65b9\u6cd5\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b0\u30eb\u30fc\u30d7\u3068NACL\u306e\u8a2d\u5b9a\u4f8b<\/h3>\n\n\n\n<p><strong>1. \u591a\u5c64\u9632\u5fa1\u306e\u305f\u3081\u306e\u5305\u62ec\u7684\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Network ACL\u306e\u8a2d\u5b9a\nresource \"aws_network_acl\" \"main\" {\n  vpc_id = aws_vpc.main.id\n\n  ingress {\n    protocol   = \"tcp\"\n    rule_no    = 100\n    action     = \"allow\"\n    cidr_block = \"0.0.0.0\/0\"\n    from_port  = 80\n    to_port    = 80\n  }\n\n  ingress {\n    protocol   = \"tcp\"\n    rule_no    = 110\n    action     = \"allow\"\n    cidr_block = \"0.0.0.0\/0\"\n    from_port  = 443\n    to_port    = 443\n  }\n\n  ingress {\n    protocol   = \"tcp\"\n    rule_no    = 120\n    action     = \"allow\"\n    cidr_block = var.admin_ip_range\n    from_port  = 22\n    to_port    = 22\n  }\n\n  # \u623b\u308a\u901a\u4fe1\u306e\u8a31\u53ef\n  egress {\n    protocol   = \"tcp\"\n    rule_no    = 100\n    action     = \"allow\"\n    cidr_block = \"0.0.0.0\/0\"\n    from_port  = 1024\n    to_port    = 65535\n  }\n\n  tags = {\n    Name = \"main-nacl\"\n  }\n}\n\n# \u968e\u5c64\u5316\u3055\u308c\u305f\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b0\u30eb\u30fc\u30d7\u306e\u5b9a\u7fa9\nresource \"aws_security_group\" \"alb\" {\n  name        = \"alb-security-group\"\n  description = \"Security group for ALB\"\n  vpc_id      = aws_vpc.main.id\n\n  ingress {\n    from_port   = 80\n    to_port     = 80\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  ingress {\n    from_port   = 443\n    to_port     = 443\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  egress {\n    from_port   = 0\n    to_port     = 0\n    protocol    = \"-1\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  tags = {\n    Name = \"alb-sg\"\n  }\n}\n\nresource \"aws_security_group\" \"app\" {\n  name        = \"app-security-group\"\n  description = \"Security group for application servers\"\n  vpc_id      = aws_vpc.main.id\n\n  # ALB\u304b\u3089\u306e\u901a\u4fe1\u306e\u307f\u3092\u8a31\u53ef\n  ingress {\n    from_port       = 80\n    to_port         = 80\n    protocol        = \"tcp\"\n    security_groups = [aws_security_group.alb.id]\n  }\n\n  # \u7ba1\u7406\u7528SSH\u30a2\u30af\u30bb\u30b9\n  ingress {\n    from_port   = 22\n    to_port     = 22\n    protocol    = \"tcp\"\n    cidr_blocks = [var.admin_ip_range]\n  }\n\n  egress {\n    from_port   = 0\n    to_port     = 0\n    protocol    = \"-1\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  tags = {\n    Name = \"app-sg\"\n  }\n}\n\n# \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u7528\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b0\u30eb\u30fc\u30d7\nresource \"aws_security_group\" \"db\" {\n  name        = \"db-security-group\"\n  description = \"Security group for database instances\"\n  vpc_id      = aws_vpc.main.id\n\n  ingress {\n    from_port       = 3306\n    to_port         = 3306\n    protocol        = \"tcp\"\n    security_groups = [aws_security_group.app.id]\n  }\n\n  tags = {\n    Name = \"db-sg\"\n  }\n}<\/pre>\n\n\n\n<p><strong>2. WAF\u306e\u8a2d\u5b9a\u306b\u3088\u308bWeb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4fdd\u8b77<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># WAF\u306e\u8a2d\u5b9a\nresource \"aws_wafv2_web_acl\" \"main\" {\n  name        = \"main-waf-acl\"\n  description = \"WAF ACL for main application\"\n  scope       = \"REGIONAL\"\n\n  default_action {\n    allow {}\n  }\n\n  # SQL\u30a4\u30f3\u30b8\u30a7\u30af\u30b7\u30e7\u30f3\u5bfe\u7b56\n  rule {\n    name     = \"SQLInjectionRule\"\n    priority = 1\n\n    override_action {\n      none {}\n    }\n\n    statement {\n      managed_rule_group_statement {\n        name        = \"AWSManagedRulesSQLiRuleSet\"\n        vendor_name = \"AWS\"\n      }\n    }\n\n    visibility_config {\n      cloudwatch_metrics_enabled = true\n      metric_name               = \"SQLInjectionMetric\"\n      sampled_requests_enabled  = true\n    }\n  }\n\n  # \u4e00\u822c\u7684\u306a\u653b\u6483\u306e\u9632\u5fa1\n  rule {\n    name     = \"CommonAttackRule\"\n    priority = 2\n\n    override_action {\n      none {}\n    }\n\n    statement {\n      managed_rule_group_statement {\n        name        = \"AWSManagedRulesCommonRuleSet\"\n        vendor_name = \"AWS\"\n      }\n    }\n\n    visibility_config {\n      cloudwatch_metrics_enabled = true\n      metric_name               = \"CommonAttackMetric\"\n      sampled_requests_enabled  = true\n    }\n  }\n\n  visibility_config {\n    cloudwatch_metrics_enabled = true\n    metric_name               = \"MainACLMetric\"\n    sampled_requests_enabled  = true\n  }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-16\">\u30bf\u30b0\u4ed8\u3051\u306b\u3088\u308b\u30b3\u30b9\u30c8\u7ba1\u7406\u306e\u81ea\u52d5\u5316<\/h3>\n\n\n\n<p><strong>1. \u4f53\u7cfb\u7684\u306a\u30bf\u30b0\u4ed8\u3051\u6226\u7565\u306e\u5b9f\u88c5<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30bf\u30b0\u4ed8\u3051\u306e\u5171\u901a\u30ed\u30fc\u30ab\u30eb\u5909\u6570\nlocals {\n  common_tags = {\n    Environment = var.environment\n    Project     = var.project_name\n    Owner       = var.team_name\n    ManagedBy   = \"Terraform\"\n  }\n\n  # \u30b3\u30b9\u30c8\u914d\u5206\u7528\u306e\u30bf\u30b0\n  cost_tags = {\n    CostCenter = var.cost_center\n    Department = var.department\n  }\n\n  # \u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u7ba1\u7406\u7528\u306e\u30bf\u30b0\n  lifecycle_tags = {\n    Backup      = \"true\"\n    Maintenance = \"weekend\"\n  }\n}\n\n# EC2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3078\u306e\u30bf\u30b0\u4ed8\u3051\u4f8b\nresource \"aws_instance\" \"app\" {\n  # ... \u4ed6\u306e\u8a2d\u5b9a\n\n  tags = merge(\n    local.common_tags,\n    local.cost_tags,\n    local.lifecycle_tags,\n    {\n      Name = \"app-server-${count.index + 1}\"\n    }\n  )\n}\n\n# \u81ea\u52d5\u505c\u6b62\u30fb\u8d77\u52d5\u306e\u8a2d\u5b9a\nresource \"aws_cloudwatch_event_rule\" \"stop_instances\" {\n  name                = \"stop-instances-evening\"\n  description         = \"Stop instances in the evening\"\n  schedule_expression = \"cron(0 21 ? * MON-FRI *)\"  # \u5e73\u65e521\u6642\u306b\u505c\u6b62\n}\n\nresource \"aws_cloudwatch_event_target\" \"stop_instances\" {\n  rule      = aws_cloudwatch_event_rule.stop_instances.name\n  target_id = \"StopInstances\"\n  arn       = \"arn:aws:ssm:${var.region}:${data.aws_caller_identity.current.account_id}:automation-definition\/AWS-StopEC2Instance\"\n\n  input = jsonencode({\n    InstanceId = [\n      for instance in aws_instance.app : instance.id\n    ]\n  })\n}<\/pre>\n\n\n\n<p><strong>2. \u30b3\u30b9\u30c8\u6700\u9069\u5316\u306e\u305f\u3081\u306e\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u30dd\u30ea\u30b7\u30fc<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># S3\u30d0\u30b1\u30c3\u30c8\u306e\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u30dd\u30ea\u30b7\u30fc\nresource \"aws_s3_bucket_lifecycle_configuration\" \"main\" {\n  bucket = aws_s3_bucket.main.id\n\n  rule {\n    id     = \"transition-to-ia\"\n    status = \"Enabled\"\n\n    transition {\n      days          = 30\n      storage_class = \"STANDARD_IA\"\n    }\n\n    transition {\n      days          = 60\n      storage_class = \"GLACIER\"\n    }\n\n    expiration {\n      days = 90\n    }\n  }\n}\n\n# EBS\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u7ba1\u7406\nresource \"aws_dlm_lifecycle_policy\" \"ebs_backup\" {\n  description        = \"EBS snapshot lifecycle policy\"\n  execution_role_arn = aws_iam_role.dlm_lifecycle_role.arn\n  state              = \"ENABLED\"\n\n  policy_details {\n    resource_types = [\"VOLUME\"]\n\n    schedule {\n      name = \"2 weeks of daily snapshots\"\n\n      create_rule {\n        interval      = 24\n        interval_unit = \"HOURS\"\n        times        = [\"23:45\"]\n      }\n\n      retain_rule {\n        count = 14\n      }\n\n      copy_tags = true\n    }\n\n    target_tags = {\n      Backup = \"true\"\n    }\n  }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u8a2d\u5b9a\u306b\u3088\u308a\u3001\u30bb\u30ad\u30e5\u30a2\u3067\u30b3\u30b9\u30c8\u52b9\u7387\u306e\u826f\u3044\u30a4\u30f3\u30d5\u30e9\u74b0\u5883\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30c1\u30fc\u30e0\u958b\u767a\u306e\u305f\u3081\u306eTerraform\u904b\u7528\u30ac\u30a4\u30c9\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-17\">\u30c1\u30fc\u30e0\u958b\u767a\u306e\u305f\u3081\u306eTerraform\u904b\u7528\u30ac\u30a4\u30c9<\/h2>\n\n\n\n<p>\u30c1\u30fc\u30e0\u3067Terraform\u3092\u4f7f\u7528\u3057\u305f\u30a4\u30f3\u30d5\u30e9\u69cb\u7bc9\u3092\u884c\u3046\u5834\u5408\u3001\u52b9\u7387\u7684\u306a\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3068\u9069\u5207\u306a\u5909\u66f4\u7ba1\u7406\u304c\u91cd\u8981\u3067\u3059\u3002\u3053\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001Git\u3068CICD\u9023\u643a\u306b\u3088\u308b\u52b9\u679c\u7684\u306a\u30c1\u30fc\u30e0\u958b\u767a\u306e\u65b9\u6cd5\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">Git\u3068CICD\u9023\u643a\u306b\u3088\u308b\u30a4\u30f3\u30d5\u30e9\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u7ba1\u7406<\/h3>\n\n\n\n<p><strong>1. Git\u30ea\u30dd\u30b8\u30c8\u30ea\u3068\u30d6\u30e9\u30f3\u30c1Strategy<\/strong><\/p>\n\n\n\n<p>\u63a8\u5968\u3055\u308c\u308b\u30ea\u30dd\u30b8\u30c8\u30ea\u69cb\u9020\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">terraform-infrastructure\/\n\u251c\u2500\u2500 environments\/\n\u2502   \u251c\u2500\u2500 dev\/\n\u2502   \u2502   \u251c\u2500\u2500 main.tf\n\u2502   \u2502   \u251c\u2500\u2500 variables.tf\n\u2502   \u2502   \u2514\u2500\u2500 terraform.tfvars\n\u2502   \u251c\u2500\u2500 staging\/\n\u2502   \u2502   \u251c\u2500\u2500 main.tf\n\u2502   \u2502   \u251c\u2500\u2500 variables.tf\n\u2502   \u2502   \u2514\u2500\u2500 terraform.tfvars\n\u2502   \u2514\u2500\u2500 prod\/\n\u2502       \u251c\u2500\u2500 main.tf\n\u2502       \u251c\u2500\u2500 variables.tf\n\u2502       \u2514\u2500\u2500 terraform.tfvars\n\u251c\u2500\u2500 modules\/\n\u2502   \u251c\u2500\u2500 vpc\/\n\u2502   \u251c\u2500\u2500 ec2\/\n\u2502   \u2514\u2500\u2500 rds\/\n\u2514\u2500\u2500 .github\/\n    \u2514\u2500\u2500 workflows\/\n        \u251c\u2500\u2500 terraform-plan.yml\n        \u2514\u2500\u2500 terraform-apply.yml<\/pre>\n\n\n\n<p><strong>2. GitHub Actions\u306b\u3088\u308b\u81ea\u52d5\u5316\u306e\u5b9f\u88c5<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># .github\/workflows\/terraform-plan.yml\nname: 'Terraform Plan'\n\non:\n  pull_request:\n    branches:\n      - main\n    paths:\n      - 'environments\/**'\n      - 'modules\/**'\n\njobs:\n  terraform:\n    name: 'Terraform Plan'\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout\n      uses: actions\/checkout@v2\n\n    - name: Configure AWS Credentials\n      uses: aws-actions\/configure-aws-credentials@v1\n      with:\n        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n        aws-region: ap-northeast-1\n\n    - name: Setup Terraform\n      uses: hashicorp\/setup-terraform@v1\n      with:\n        terraform_version: 1.0.0\n\n    - name: Terraform Format\n      id: fmt\n      run: terraform fmt -check\n      working-directory: environments\/dev\n\n    - name: Terraform Init\n      id: init\n      run: terraform init\n      working-directory: environments\/dev\n\n    - name: Terraform Validate\n      id: validate\n      run: terraform validate\n      working-directory: environments\/dev\n\n    - name: Terraform Plan\n      id: plan\n      run: terraform plan -no-color\n      working-directory: environments\/dev\n      continue-on-error: true\n\n    - name: Update Pull Request\n      uses: actions\/github-script@v3\n      with:\n        github-token: ${{ secrets.GITHUB_TOKEN }}\n        script: |\n          const output = `#### Terraform Format and Style \ud83d\udd8c\\`${{ steps.fmt.outcome }}\\`\n          #### Terraform Initialization \u2699\ufe0f\\`${{ steps.init.outcome }}\\`\n          #### Terraform Validation \ud83e\udd16\\`${{ steps.validate.outcome }}\\`\n          #### Terraform Plan \ud83d\udcd6\\`${{ steps.plan.outcome }}\\`\n\n          &lt;details&gt;&lt;summary&gt;Show Plan&lt;\/summary&gt;\n\n          \\`\\`\\`\\n\n          ${process.env.PLAN}\n          \\`\\`\\`\n\n          &lt;\/details&gt;`;\n\n          github.issues.createComment({\n            issue_number: context.issue.number,\n            owner: context.repo.owner,\n            repo: context.repo.repo,\n            body: output\n          })<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># .github\/workflows\/terraform-apply.yml\nname: 'Terraform Apply'\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - 'environments\/**'\n      - 'modules\/**'\n\njobs:\n  terraform:\n    name: 'Terraform Apply'\n    runs-on: ubuntu-latest\n    environment: production\n\n    steps:\n    - name: Checkout\n      uses: actions\/checkout@v2\n\n    - name: Configure AWS Credentials\n      uses: aws-actions\/configure-aws-credentials@v1\n      with:\n        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n        aws-region: ap-northeast-1\n\n    - name: Setup Terraform\n      uses: hashicorp\/setup-terraform@v1\n      with:\n        terraform_version: 1.0.0\n\n    - name: Terraform Init\n      run: terraform init\n      working-directory: environments\/prod\n\n    - name: Terraform Apply\n      run: terraform apply -auto-approve\n      working-directory: environments\/prod<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">\u30c1\u30fc\u30e0\u3067\u306e\u627f\u8a8d\u30d5\u30ed\u30fc\u3068\u5909\u66f4\u7ba1\u7406\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p><strong>1. \u30c6\u30e9\u30d5\u30a9\u30fc\u30e0\u5909\u66f4\u7ba1\u7406\u30dd\u30ea\u30b7\u30fc<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u5909\u66f4\u7ba1\u7406\u7528\u306eDynamoDB\u30c6\u30fc\u30d6\u30eb\nresource \"aws_dynamodb_table\" \"terraform_changes\" {\n  name           = \"terraform-changes\"\n  billing_mode   = \"PAY_PER_REQUEST\"\n  hash_key       = \"ChangeID\"\n  range_key      = \"Timestamp\"\n\n  attribute {\n    name = \"ChangeID\"\n    type = \"S\"\n  }\n\n  attribute {\n    name = \"Timestamp\"\n    type = \"S\"\n  }\n\n  tags = {\n    Name = \"terraform-changes\"\n  }\n}\n\n# \u5909\u66f4\u5c65\u6b74\u3092\u8a18\u9332\u3059\u308bLambda\u95a2\u6570\nresource \"aws_lambda_function\" \"record_changes\" {\n  filename      = \"record_changes.zip\"\n  function_name = \"terraform-record-changes\"\n  role          = aws_iam_role.lambda_role.arn\n  handler       = \"index.handler\"\n  runtime       = \"nodejs14.x\"\n\n  environment {\n    variables = {\n      DYNAMODB_TABLE = aws_dynamodb_table.terraform_changes.name\n    }\n  }\n}\n\n# SNS\u30c8\u30d4\u30c3\u30af\u3092\u4f5c\u6210\u3057\u3066\u5909\u66f4\u901a\u77e5\u3092\u9001\u4fe1\nresource \"aws_sns_topic\" \"terraform_changes\" {\n  name = \"terraform-changes\"\n}\n\nresource \"aws_sns_topic_subscription\" \"email\" {\n  topic_arn = aws_sns_topic.terraform_changes.arn\n  protocol  = \"email\"\n  endpoint  = var.notification_email\n}<\/pre>\n\n\n\n<p><strong>2. \u30c1\u30fc\u30e0\u958b\u767a\u306e\u305f\u3081\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u5316\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># modules\/service\/variables.tf\nvariable \"service_name\" {\n  description = \"\u30b5\u30fc\u30d3\u30b9\u306e\u540d\u524d\"\n  type        = string\n  validation {\n    condition     = can(regex(\"^[a-z0-9-]+$\", var.service_name))\n    error_message = \"\u30b5\u30fc\u30d3\u30b9\u540d\u306f\u5c0f\u6587\u5b57\u306e\u30a2\u30eb\u30d5\u30a1\u30d9\u30c3\u30c8\u3001\u6570\u5b57\u3001\u30cf\u30a4\u30d5\u30f3\u306e\u307f\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002\"\n  }\n}\n\nvariable \"environment\" {\n  description = \"\u74b0\u5883\u540d\"\n  type        = string\n  validation {\n    condition     = contains([\"dev\", \"staging\", \"prod\"], var.environment)\n    error_message = \"\u74b0\u5883\u540d\u306f'dev'\u3001'staging'\u3001'prod'\u306e\u3044\u305a\u308c\u304b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\"\n  }\n}\n\n# modules\/service\/outputs.tf\noutput \"service_url\" {\n  description = \"\u30b5\u30fc\u30d3\u30b9\u306e\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8URL\"\n  value       = aws_lb.main.dns_name\n}\n\noutput \"monitoring_dashboard_url\" {\n  description = \"\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u306eURL\"\n  value       = aws_cloudwatch_dashboard.main.dashboard_arn\n}<\/pre>\n\n\n\n<p><strong>3. \u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3<\/strong><\/p>\n\n\n\n<p>\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8\u306e\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Terraform\u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8\n\n## \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\n- [ ] \u9069\u5207\u306aIAM\u30dd\u30ea\u30b7\u30fc\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u304b\n- [ ] \u6a5f\u5bc6\u60c5\u5831\u304c\u76f4\u63a5\u30b3\u30fc\u30c9\u306b\u542b\u307e\u308c\u3066\u3044\u306a\u3044\u304b\n- [ ] \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b0\u30eb\u30fc\u30d7\u306e\u30eb\u30fc\u30eb\u306f\u6700\u5c0f\u6a29\u9650\u306e\u539f\u5247\u306b\u5f93\u3063\u3066\u3044\u308b\u304b\n\n## \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30b3\u30b9\u30c8\n- [ ] \u30ea\u30bd\u30fc\u30b9\u306e\u30b5\u30a4\u30b8\u30f3\u30b0\u306f\u9069\u5207\u304b\n- [ ] \u30b3\u30b9\u30c8\u6700\u9069\u5316\u306e\u305f\u3081\u306e\u30bf\u30b0\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u304b\n- [ ] \u81ea\u52d5\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u306e\u8a2d\u5b9a\u306f\u9069\u5207\u304b\n\n## \u53ef\u7528\u6027\u3068\u4fe1\u983c\u6027\n- [ ] \u30de\u30eb\u30c1AZ\u69cb\u6210\u306b\u306a\u3063\u3066\u3044\u308b\u304b\n- [ ] \u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u8a2d\u5b9a\u306f\u9069\u5207\u304b\n- [ ] \u76e3\u8996\u3068\u30a2\u30e9\u30fc\u30c8\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u304b\n\n## \u30b3\u30fc\u30c9\u54c1\u8cea\n- [ ] \u547d\u540d\u898f\u5247\u306f\u7d71\u4e00\u3055\u308c\u3066\u3044\u308b\u304b\n- [ ] \u30b3\u30fc\u30c9\u306f\u9069\u5207\u306b\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3055\u308c\u3066\u3044\u308b\u304b\n- [ ] \u5909\u6570\u3068\u30a2\u30a6\u30c8\u30d7\u30c3\u30c8\u306f\u9069\u5207\u306b\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5316\u3055\u308c\u3066\u3044\u308b\u304b<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u8a2d\u5b9a\u3068\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u306b\u3088\u308a\u3001\u30c1\u30fc\u30e0\u3067\u306e\u52b9\u7387\u7684\u306aTerraform\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3088\u304f\u3042\u308b\u30c8\u30e9\u30d6\u30eb\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-20\">\u3088\u304f\u3042\u308b\u30c8\u30e9\u30d6\u30eb\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5<\/h2>\n\n\n\n<p>Terraform\u3092\u4f7f\u7528\u3057\u305fAWS\u30a4\u30f3\u30d5\u30e9\u69cb\u7bc9\u306b\u304a\u3044\u3066\u3001\u69d8\u3005\u306a\u30c8\u30e9\u30d6\u30eb\u306b\u906d\u9047\u3059\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002\u3053\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u4ee3\u8868\u7684\u306a\u30c8\u30e9\u30d6\u30eb\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u30b9\u30c6\u30fc\u30c8\u554f\u984c\u306e\u9632\u6b62\u3068\u89e3\u6c7a\u65b9\u6cd5<\/h3>\n\n\n\n<p><strong>1. \u30b9\u30c6\u30fc\u30c8\u7af6\u5408\u306e\u554f\u984c<\/strong><\/p>\n\n\n\n<p>\u30b9\u30c6\u30fc\u30c8\u7af6\u5408\u306f\u8907\u6570\u306e\u30e6\u30fc\u30b6\u30fc\u304c\u540c\u6642\u306b\u5909\u66f4\u3092\u9069\u7528\u3057\u3088\u3046\u3068\u3057\u305f\u969b\u306b\u767a\u751f\u3059\u308b\u4e00\u822c\u7684\u306a\u554f\u984c\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30b9\u30c6\u30fc\u30c8\u306e\u30ed\u30c3\u30af\u7ba1\u7406\u306e\u5b9f\u88c5\u4f8b\nterraform {\n  backend \"s3\" {\n    bucket         = \"terraform-state-bucket\"\n    key            = \"terraform.tfstate\"\n    region         = \"ap-northeast-1\"\n    encrypt        = true\n    dynamodb_table = \"terraform-state-lock\"\n  }\n}\n\n# DynamoDB\u306b\u3088\u308b\u30b9\u30c6\u30fc\u30c8\u30ed\u30c3\u30af\u30c6\u30fc\u30d6\u30eb\nresource \"aws_dynamodb_table\" \"terraform_state_lock\" {\n  name           = \"terraform-state-lock\"\n  billing_mode   = \"PAY_PER_REQUEST\"\n  hash_key       = \"LockID\"\n  attribute {\n    name = \"LockID\"\n    type = \"S\"\n  }\n\n  tags = {\n    Name = \"terraform-state-lock\"\n  }\n}<\/pre>\n\n\n\n<p><strong>\u30b9\u30c6\u30fc\u30c8\u7af6\u5408\u304c\u767a\u751f\u3057\u305f\u5834\u5408\u306e\u89e3\u6c7a\u624b\u9806\uff1a<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ed\u30c3\u30af\u306e\u5f37\u5236\u89e3\u9664\uff08\u7dca\u6025\u6642\u306e\u307f\uff09<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ed\u30c3\u30af\u306e\u5f37\u5236\u89e3\u9664\nterraform force-unlock LOCK_ID<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30b9\u30c6\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u73fe\u5728\u306e\u30b9\u30c6\u30fc\u30c8\u3092\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\nterraform state pull &gt; terraform.tfstate.backup<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30b9\u30c6\u30fc\u30c8\u306e\u4fee\u5fa9<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30b9\u30c6\u30fc\u30c8\u306e\u4e00\u89a7\u8868\u793a\nterraform state list\n\n# \u7279\u5b9a\u306e\u30ea\u30bd\u30fc\u30b9\u306e\u30b9\u30c6\u30fc\u30c8\u524a\u9664\uff08\u5fc5\u8981\u306a\u5834\u5408\uff09\nterraform state rm 'aws_instance.example'\n\n# \u30b9\u30c6\u30fc\u30c8\u306e\u66f4\u65b0\nterraform refresh<\/pre>\n\n\n\n<p><strong>2. \u30b9\u30c6\u30fc\u30c8\u640d\u5931\u6642\u306e\u5fa9\u65e7\u624b\u9806<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># S3\u30d0\u30b1\u30c3\u30c8\u306e\u30d0\u30fc\u30b8\u30e7\u30cb\u30f3\u30b0\u5c65\u6b74\u304b\u3089\u5fa9\u5143\naws s3api list-object-versions \\\n    --bucket terraform-state-bucket \\\n    --prefix terraform.tfstate\n\n# \u7279\u5b9a\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u5fa9\u5143\naws s3api get-object \\\n    --bucket terraform-state-bucket \\\n    --key terraform.tfstate \\\n    --version-id \"VERSION_ID\" \\\n    terraform.tfstate.restored<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u4f9d\u5b58\u95a2\u4fc2\u30a8\u30e9\u30fc\u3078\u306e\u5bfe\u51e6\u65b9\u6cd5<\/h3>\n\n\n\n<p><strong>1. \u6697\u9ed9\u7684\u4f9d\u5b58\u95a2\u4fc2\u306e\u554f\u984c\u89e3\u6c7a<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u660e\u793a\u7684\u306a\u4f9d\u5b58\u95a2\u4fc2\u306e\u5b9a\u7fa9\nresource \"aws_instance\" \"app\" {\n  # ... \u4ed6\u306e\u8a2d\u5b9a\n\n  depends_on = [\n    aws_vpc.main,\n    aws_subnet.app,\n    aws_security_group.app\n  ]\n}\n\n# \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u9069\u5207\u306a\u4f7f\u7528\ndata \"aws_vpc\" \"existing\" {\n  id = var.vpc_id\n}\n\nresource \"aws_security_group\" \"app\" {\n  name        = \"app-sg\"\n  description = \"Application security group\"\n  vpc_id      = data.aws_vpc.existing.id\n\n  # ... \u4ed6\u306e\u8a2d\u5b9a\n}<\/pre>\n\n\n\n<p><strong>2. \u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\u9806\u5e8f\u306e\u5236\u5fa1<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ab\u30a6\u30f3\u30c8\u3068\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u7d44\u307f\u5408\u308f\u305b\u305f\u4f9d\u5b58\u95a2\u4fc2\u5236\u5fa1\nresource \"aws_instance\" \"app\" {\n  count = var.instance_count\n\n  ami           = data.aws_ami.app.id\n  instance_type = var.instance_type\n  subnet_id     = element(aws_subnet.private[*].id, count.index % length(aws_subnet.private))\n\n  lifecycle {\n    create_before_destroy = true\n\n    precondition {\n      condition     = data.aws_subnet.private[count.index % length(aws_subnet.private)].state == \"available\"\n      error_message = \"\u30b5\u30d6\u30cd\u30c3\u30c8\u304c\u5229\u7528\u53ef\u80fd\u306a\u72b6\u614b\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\"\n    }\n  }\n}<\/pre>\n\n\n\n<p><strong>3. \u3088\u304f\u3042\u308b\u4f9d\u5b58\u95a2\u4fc2\u30a8\u30e9\u30fc\u3068\u30c7\u30d0\u30c3\u30b0\u65b9\u6cd5<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30c7\u30d0\u30c3\u30b0\u7528\u306enull\u30ea\u30bd\u30fc\u30b9\nresource \"null_resource\" \"debug\" {\n  triggers = {\n    vpc_id     = aws_vpc.main.id\n    subnet_ids = join(\",\", aws_subnet.private[*].id)\n  }\n\n  provisioner \"local-exec\" {\n    command = &lt;&lt;-EOT\n      echo \"VPC ID: ${aws_vpc.main.id}\"\n      echo \"Subnet IDs: ${join(\",\", aws_subnet.private[*].id)}\"\n    EOT\n  }\n}\n\n# \u30ea\u30bd\u30fc\u30b9\u306e\u72b6\u614b\u78ba\u8a8d\u7528\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\ndata \"aws_vpc\" \"debug\" {\n  id = aws_vpc.main.id\n\n  lifecycle {\n    postcondition {\n      condition     = self.state == \"available\"\n      error_message = \"VPC\u304c\u5229\u7528\u53ef\u80fd\u306a\u72b6\u614b\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\"\n    }\n  }\n}<\/pre>\n\n\n\n<p><strong>\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ed\u30b0\u3068\u8a3a\u65ad\u60c5\u5831\u306e\u53ce\u96c6<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u8a73\u7d30\u306a\u30ed\u30b0\u51fa\u529b\u306e\u6709\u52b9\u5316\nexport TF_LOG=DEBUG\nexport TF_LOG_PATH=terraform.log\n\n# \u30d7\u30e9\u30f3\u306e\u8a73\u7d30\u51fa\u529b\nterraform plan -detailed-exitcode<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u6bb5\u968e\u7684\u306a\u30c7\u30d0\u30c3\u30b0<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u7279\u5b9a\u306e\u30ea\u30bd\u30fc\u30b9\u306e\u307f\u3092\u5bfe\u8c61\u3068\u3057\u305f\u64cd\u4f5c\nterraform plan -target=aws_instance.app\nterraform apply -target=aws_instance.app\n\n# \u7279\u5b9a\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u691c\u8a3c\nterraform validate -json | jq<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u4e00\u822c\u7684\u306a\u30a8\u30e9\u30fc\u3068\u5bfe\u51e6\u6cd5<\/strong><\/li>\n<\/ol>\n\n\n\n<p>\u30a8\u30e9\u30fc\u30d1\u30bf\u30fc\u30f3\u3068\u89e3\u6c7a\u65b9\u6cd5\u306e\u4e00\u89a7\uff1a<\/p>\n\n\n<div id=\"id-2e53a69a-f35e-4629-9966-5479de40ee2d\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8<\/th><th>\u8003\u3048\u3089\u308c\u308b\u539f\u56e0<\/th><th>\u89e3\u6c7a\u65b9\u6cd5<\/th><\/tr><\/thead><tbody><tr><td>Error: Error acquiring the state lock<\/td><td>\u4ed6\u306e\u30e6\u30fc\u30b6\u30fc\u304c\u64cd\u4f5c\u4e2d<\/td><td><code>terraform force-unlock<\/code> \u306e\u4f7f\u7528\u3092\u691c\u8a0e<\/td><\/tr><tr><td>Error: Resource not found<\/td><td>\u30ea\u30bd\u30fc\u30b9\u304c\u65e2\u306b\u524a\u9664\u3055\u308c\u3066\u3044\u308b<\/td><td><code>terraform refresh<\/code> \u3067\u72b6\u614b\u3092\u66f4\u65b0<\/td><\/tr><tr><td>Error: Provider configuration not present<\/td><td>\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u8a2d\u5b9a\u4e0d\u8db3<\/td><td><code>terraform init<\/code> \u306e\u518d\u5b9f\u884c<\/td><\/tr><tr><td>Error: Invalid block definition<\/td><td>HCL\u69cb\u6587\u30a8\u30e9\u30fc<\/td><td>\u30b3\u30fc\u30c9\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306e\u78ba\u8a8d\u3068\u4fee\u6b63<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>\u30c8\u30e9\u30d6\u30eb\u4e88\u9632\u306e\u305f\u3081\u306e\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[ ] <code>terraform fmt<\/code> \u306b\u3088\u308b\u30b3\u30fc\u30c9\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>[ ] <code>terraform validate<\/code> \u306b\u3088\u308b\u69cb\u6587\u30c1\u30a7\u30c3\u30af<\/li>\n\n\n\n<li>[ ] <code>terraform plan<\/code> \u306e\u5b9f\u884c\u7d50\u679c\u306e\u614e\u91cd\u306a\u30ec\u30d3\u30e5\u30fc<\/li>\n\n\n\n<li>[ ] \u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u8a2d\u5b9a\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>[ ] \u5fc5\u8981\u306a\u6a29\u9650\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>[ ] \u4f9d\u5b58\u95a2\u4fc2\u306e\u660e\u793a\u7684\u306a\u5b9a\u7fa9<\/li>\n\n\n\n<li>[ ] \u30ea\u30bd\u30fc\u30b9\u540d\u306e\u91cd\u8907\u30c1\u30a7\u30c3\u30af<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u624b\u6cd5\u3092\u7406\u89e3\u3057\u3001\u9069\u5207\u306b\u5bfe\u5fdc\u3059\u308b\u3053\u3068\u3067\u3001Terraform\u3092\u4f7f\u7528\u3057\u305fAWS\u30a4\u30f3\u30d5\u30e9\u69cb\u7bc9\u3092\u3088\u308a\u78ba\u5b9f\u306b\u9032\u3081\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":{"0":"post-2267","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-aws","7":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2267"}],"version-history":[{"count":1,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2267\/revisions"}],"predecessor-version":[{"id":2268,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2267\/revisions\/2268"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}