본문 바로가기
AWS

AWS CloudFormation (2)- 웹 애플리케이션 배포 및 관리 실습

by 장중앙 2021. 8. 25.

웹 응용프로그래밍 배포

스택 생성

스택 생성을 위한 탬플릿 작성

WebApplication.json

더보기

{

  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.",

  "Parameters" : {

     "InstanceType" : {   <==사용자가 결정 사용할 인스턴스의 유형을 AllowedValues에서 결정할 수 있음

       "Description" : "WebServer EC2 instance type",

       "Type" : "String",

       "Default" : "t2.nano",

       "AllowedValues" : [ 

         "t1.micro", 

         "t2.nano",

         "t2.micro", 

         "t2.small"

       ],

       "ConstraintDescription" : "must be a valid EC2 instance type."

     }

   },

   "Mappings" : {

     "AWSInstanceType2Arch" : {

       "t1.micro"    : { "Arch" : "HVM64"  },

       "t2.nano"     : { "Arch" : "HVM64"  },

       "t2.micro"    : { "Arch" : "HVM64"  },

      "t2.small"    : { "Arch" : "HVM64"  }

     },

     "AWSRegionArch2AMI" : {

       "us-east-1"        : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"},

       "us-west-2"        : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"},

       "us-west-1"        : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"},

       "eu-west-1"        : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"},

       "eu-west-2"        : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"},

       "eu-west-3"        : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"},

       "eu-central-1"     : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"},

       "ap-northeast-1"   : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"},

       "ap-northeast-2"   : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"},

       "ap-northeast-3"   : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"},

       "ap-southeast-1"   : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"},

       "ap-southeast-2"   : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"},

       "ap-south-1"       : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"},

       "us-east-2"        : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"},

       "ca-central-1"     : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"},

       "sa-east-1"        : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"},

       "cn-north-1"       : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"},

       "cn-northwest-1"   : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"}

     }

   },

   "Resources" : {

     "WebServerInstance": {  

       "Type" : "AWS::EC2::Instance",

       "Metadata" : {

         "Comment" : "Install a simple PHP application",

         "AWS::CloudFormation::Init" : {  <==인스턴스가 실행될 때 아래의 내용을 실행

           "config" : {

             "packages" : {

               "yum" : {

                 "httpd"             : [],

                 "php"               : []

               }

             },

             "files" : {

               "/var/www/html/index.php" : {

                 "content" : { "Fn::Join" : ["", [

                   "<?php\n",

                   "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",

                   "?>\n"

                 ]]},

                 "mode"    : "000644",

                 "owner"   : "apache",

                 "group"   : "apache"

               },

               "/etc/cfn/cfn-hup.conf" : {

                 "content" : { "Fn::Join" : ["", [

                   "[main]\n",

                   "stack=", { "Ref" : "AWS::StackId" }, "\n",

                   "region=", { "Ref" : "AWS::Region" }, "\n"

                 ]]},

                 "mode" : "000400",

                 "owner" : "root",

                 "group" : "root"

               },

               "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : {

                 "content": { "Fn::Join" : ["", [

                   "[cfn-auto-reloader-hook]\n","triggers=post.update\n","path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServerInstance "," --region ", { "Ref" : "AWS::Region" }, "\n",

                   "runas=root\n"

                 ]]}

               }

             },

             "services" : {

               "sysvinit" : {

                 "httpd"    : { "enabled" : "true", "ensureRunning" : "true" },

                 "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true",

                     "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]}

               }

             }

           }

         }

       },

       "Properties": {

         "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, <=="Ref" : "InstanceType" 사용자가 정한 값에 맞는 arch 타입을 선택

         "InstanceType" : { "Ref" : "InstanceType" },

         "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ],

         "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [

              "#!/bin/bash -xe\n",

              "yum install -y aws-cfn-bootstrap\n",

              "# Install the files and packages from the metadata\n",

              "/opt/aws/bin/cfn-init -v ",

              "         --stack ", { "Ref" : "AWS::StackName" },

              "         --resource WebServerInstance ",

              "         --region ", { "Ref" : "AWS::Region" }, "\n",

              "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n",

              "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n",

              "# Signal the status from cfn-init\n",

              "/opt/aws/bin/cfn-signal -e $? ",

              "         --stack ", { "Ref" : "AWS::StackName" },

              "         --resource WebServerInstance ",

              "         --region ", { "Ref" : "AWS::Region" }, "\n"

         ]]}}        

       },

       "CreationPolicy" : {

         "ResourceSignal" : {

           "Timeout" : "PT5M"

         }

       }

     },

     "WebServerSecurityGroup" : {

       "Type" : "AWS::EC2::SecurityGroup",

       "Properties" : {

         "GroupDescription" : "Enable HTTP access via port 80",

         "SecurityGroupIngress" : [

           {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}

         ]

       }      

     }          

   },

   "Outputs" : {

     "WebsiteURL" : {

       "Description" : "Application URL",

       "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] }

     }

   }

 }

탬플릿에 작성 한 것과 같이 인스턴스는 {t1.micro, t2.nano, t2.micro, t2.small}중에 선택

더보기

...

"Parameters" : {

    "InstanceType" : {

      "Description" : "WebServer EC2 instance type",

      "Type" : "String",

      "Default" : "t2.nano",

      "AllowedValues" : [ 

"t1.micro", 

"t2.nano",

"t2.micro", 

"t2.small"

      ],

      "ConstraintDescription" : "must be a valid EC2 instance type."

    }

...

실습에서는 t2.nano로 진행

이후로는 기본 설정시 오류발생

더보기

No default VPC for this user (Service: AmazonEC2; Status Code: 400; Error Code: VPCIdNotSpecified; Request ID: f20eae08-9779-4fd9-a2e5-64724cd3c502; Proxy: null)

해당 계정에 할당된 기본 VPC가 존재하지 않음

기본 VPC를 생성 후 진행해야함

기본 VPC생성

생성된 기본 VPC

재생성시 정상 생성을 확인

정상생성된 스택 확인

탬플릿을 따라 생성된 보안그룹

더보기

...

"WebServerSecurityGroup" : {

      "Type" : "AWS::EC2::SecurityGroup",

      "Properties" : {

        "GroupDescription" : "Enable HTTP access via port 80",

        "SecurityGroupIngress" : [ ⇐ Adds an inbound rule to a security group.

          {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}

        ]

      }      

    }

...

사용자가 선택한 t2.nano로 만들어진 인스턴스 확인

더보기

...

"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },

...

"InstanceType" : { "Ref" : "InstanceType" },

...

생성된 서비스 확인

더보기

...

    "files" : {

              "/var/www/html/index.php" : {

                "content" : { "Fn::Join" : ["", [

                  "<?php\n",

                  "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",

                  "?>\n"

                ]]},

                "mode"    : "000644",

                "owner"   : "apache",

                "group"   : "apache"

              }

...

웹 페이지 확인

탬플릿에 대한 웹 페이지가 배포됨

 

 

EC2 인스턴스 유형 업데이트

생성된 인스턴스에 접속하기 위한 keypair를 부여, SSH접속을 위해 Security 그룹을 변경하는 리소스를 추가, 애플리케이션을 변경하는 코드를 추가하여 기존의 스택을 업데이트함

키페어 생성

생성된 키페어 확인

 

WebApplication.json파일 수정

더보기

{

  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.",

  "Parameters" : {

    "InstanceType" : {

      "Description" : "WebServer EC2 instance type",

      "Type" : "String",

      "Default" : "t2.nano",

      "AllowedValues" : [ 

"t1.micro", 

"t2.nano",

"t2.micro", 

"t2.small"

      ],

      "ConstraintDescription" : "must be a valid EC2 instance type."

    }

"KeyName" : {

"Description" : "Name of an existing EC2 key pair for SSH access", 

"Type" : "AWS::EC2::KeyPair::KeyName"

}, 

"SSHLocation" : {

"Description" : "The IP address range that can be used to SSH to the EC2 instances",

"Type" : "String", 

"MinLength" : "9", 

"MaxLength" : "18", 

"Default" : "0.0.0.0/0", 

"AllowedPattern" : "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", 

"ConstraintDescription" : "must be a valid IP CIDR range of the form x.x.x.x/x"

}

  },

  "Mappings" : {

    "AWSInstanceType2Arch" : {

"t1.micro"    : { "Arch" : "HVM64"  },

"t2.nano"     : { "Arch" : "HVM64"  },

"t2.micro"    : { "Arch" : "HVM64"  },

"t2.small"    : { "Arch" : "HVM64"  }

    },

    "AWSRegionArch2AMI" : {

      "us-east-1"        : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"},

      "us-west-2"        : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"},

      "us-west-1"        : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"},

      "eu-west-1"        : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"},

      "eu-west-2"        : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"},

      "eu-west-3"        : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"},

      "eu-central-1"     : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"},

      "ap-northeast-1"   : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"},

      "ap-northeast-2"   : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"},

      "ap-northeast-3"   : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"},

      "ap-southeast-1"   : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"},

      "ap-southeast-2"   : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"},

      "ap-south-1"       : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"},

      "us-east-2"        : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"},

      "ca-central-1"     : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"},

      "sa-east-1"        : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"},

      "cn-north-1"       : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"},

      "cn-northwest-1"   : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"}

    }

  },

  "Resources" : {

    "WebServerInstance": {  

      "Type" : "AWS::EC2::Instance",

      "Metadata" : {

        "Comment" : "Install a simple PHP application",

        "AWS::CloudFormation::Init" : {

          "config" : {

            "packages" : {

              "yum" : {

                "httpd"             : [],

                "php"               : []

              }

            },

            "files" : {

              "/var/www/html/index.php" : {

                "content" : { "Fn::Join" : ["", [

                  "<?php\n",

                  "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",

  "echo 'Upgraded version via UpdateStack';\n", 

                  "?>\n"

                ]]},

                "mode"    : "000644",

                "owner"   : "apache",

                "group"   : "apache"

              },

              "/etc/cfn/cfn-hup.conf" : {

                "content" : { "Fn::Join" : ["", [

                  "[main]\n",

                  "stack=", { "Ref" : "AWS::StackId" }, "\n",

                  "region=", { "Ref" : "AWS::Region" }, "\n"

                ]]},

                "mode" : "000400",

                "owner" : "root",

                "group" : "root"

              },

              "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : {

                "content": { "Fn::Join" : ["", [

                  "[cfn-auto-reloader-hook]\n","triggers=post.update\n","path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServerInstance "," --region ", { "Ref" : "AWS::Region" }, "\n",

                  "runas=root\n"

                ]]}

              }

            },

            "services" : {

              "sysvinit" : {

                "httpd"    : { "enabled" : "true", "ensureRunning" : "true" },

                "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true",

                    "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]}

              }

            }

          }

        }

      },

      "Properties": {

        "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },

        "InstanceType" : { "Ref" : "InstanceType" },

"KeyName" : { "Ref" : "KeyName" }, 

        "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ],

        "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [

             "#!/bin/bash -xe\n",

             "yum install -y aws-cfn-bootstrap\n",

             "# Install the files and packages from the metadata\n",

             "/opt/aws/bin/cfn-init -v ",

             "         --stack ", { "Ref" : "AWS::StackName" },

             "         --resource WebServerInstance ",

             "         --region ", { "Ref" : "AWS::Region" }, "\n",

             "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n",

             "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n",

             "# Signal the status from cfn-init\n",

             "/opt/aws/bin/cfn-signal -e $? ",

             "         --stack ", { "Ref" : "AWS::StackName" },

             "         --resource WebServerInstance ",

             "         --region ", { "Ref" : "AWS::Region" }, "\n"

        ]]}}        

      },

      "CreationPolicy" : {

        "ResourceSignal" : {

          "Timeout" : "PT5M"

        }

      }

    },

    "WebServerSecurityGroup" : {

      "Type" : "AWS::EC2::SecurityGroup",

      "Properties" : {

        "GroupDescription" : "Enable HTTP access via port 80",

        "SecurityGroupIngress" : [

          {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}, 

  {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref": "SSHLocation" }}

        ]

      }      

    }          

  },

  "Outputs" : {

    "WebsiteURL" : {

      "Description" : "Application URL",

      "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] }

    }

  }

}

스택 업데이트

변경한 탬플릿 파일 적용

인스턴스 유형은 동일하게 t2.nano, 키페어는 앞서 생성한 키페어를 선택

이후로는 기본 설정

 

정상 업데이트된 스택확인

 

이전의 인스턴스가 종료되고 새로운 인스턴스가 생성

보안그룹이 적용되어 있음(22번 포트가 열려있음)

 

웹페이지 확인

변경된 탬플릿에 대한 웹 페이지가 업데이트되어 배포됨

업데이트된 웹페이지가 정상 동작중을 확인

SSH확인

생성한 키페어를 이용하여 SSH 접속을 확인

정상 연결되는 SSH연결

댓글