정적 요소만 있는 홈페이지 즉 DB 연결이나 외부에서 데이터를 가져와서 변화하는 페이지가 아닌 단순 이미지나 JS 파일로 된 웹 사이트를 만들어야 하는 경우가 종종 있다. 혹은 동적 페이지를 개발하면서 정적 요소를 가져와야 하는 경우가 있을 것이다. 이번 글은 그러한 경우에 AWS 상에서 간단하게 만들수 있는 방법을 제시한다.

  아마존에서는 아래의 메뉴얼을 제공하고 있고 아래 메뉴얼을 보면서 따라가더라도 AWS에 익숙하지 않은 사람이라도 크게 어렵지 않게 몇십분 정도만 투자하면 금방 S3에 웹 페이지 리소스를 업로드 하고 도메인을 연결하여 웹 서비스를 구축 할수 있다. 즉 아파치니 Nginx 같은 웹 서버를 설치하고 권한을 잡아주고 기본 설정을 연결하지 않아도 된다.

  공식 메뉴얼은 아래에 있으므로 참조 하기 바란다.

https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/website-hosting-custom-domain-walkthrough.html

 

Route 53에 등록된 사용자 지정 도메인을 사용하여 정적 웹 사이트 구성 - Amazon Simple Storage Service

변경 사항은 일반적으로 60초 이내에 모든 Route 53 서버로 전파됩니다. 전파가 완료되면 이 절차에서 생성한 별칭 레코드의 이름을 사용하여 트래픽을 Amazon S3 버킷으로 라우팅할 수 있습니다.

docs.aws.amazon.com

% 아래의 글은 위의 메뉴얼과는 일부 상이하나 메뉴얼 대로 하는 것도 좋다.

1. 버킷 만들기

  제일 먼저 해야 할 일은 S3 버킷을 만들어야 한다. 버킷은 아래의 그림과 같이 기본적인 설정만을 통해서 생성하면 된다. (To-Do 참고) 다만 주의할 점이 두가지 정도 있으므로 버킷 생성시에 참고 하기 바란다.

  To-Do

1. 버킷 생성 클릭하기
2. 버킷 이름 넣기
3. 버킷의 리전을 원하는 리전으로 변경하기
4. 버킷을 퍼블릭으로 설정하기 
5. 완료

 생성시 주의해야 할 두가지 사항은 아래와 같다.

 (1). 버킷 이름

  외부에 도메인을 통해서 서비스를 하기로 하였고 도메인은  http://site.golobby.xyz으로 하기로 하였다. 그렇다면 버킷의 이름을 지정할때 해당 도메인과 동일한 이름인 site.golobby.xyz 로 설정해야 한다. 아래의 사진을 보면 버킷 이름을 내가 노출하고자 하는 도메인으로 설정한것을 알수 있다.

(2). 퍼블릭으로 설정

  기본적으로 버킷을 생성시 "이 버킷의 퍼블릭 액세스 차단 설정" 이라는 옵션이 모두 활성화 되어 있어 내부에서만 사용하도록 되어 있다. 이를 모두 풀어 주고 퍼블릭으로 설정해야 한다. 다만 이렇게 ACL의 설정 없이 모두 열어주고 정책을 줄 경우 외부에서 해당 버킷에 모두 접근할 수 있으므로 외부에 특별한 권한 없이 노출 할 수 있는 파일들만 위치 하는게 좋다. 별도로 S3 버킷의 권한에 대해서는 별도의 문서에서 알아 보겠다.

생성 완료를 클릭하면 아래와 같이 버킷이 생성된 것을 알 수 있다.

 

2. 정책 설정 하기 

 버킷이 생성되었다면 이제 정책을 설정하여 외부에서 접속이 가능하도록 설정 해야 한다. 버킷을 눌러 상세 화면에서 권한을 눌러서 "버킷 정책"으로 접속 하여 정책을 수정한다.

To-Do

1. 버킷 상세 페이지에서 "권한" 탭을 선택하고 "버킷 정책"  편집을 누른다.
2. 정책 생성기를 누루고 정책은 S3 버킷 정책으로 설정 한다.
3. 정책 생성기에서 허용, *, 그리고 Actions에는 GetObject만 설정
4. ARN에는 arn:aws:s3:::site.golobby.xyz 와 같이 적어주고 생성을 클릭
5. JSON 형식으로 뜬 정책을 클립보드에 복사
6. 정책에 복사한 다음 Resource에 ARN의 마지막 부분에 "/*" 첨부 "Resource": "arn:aws:s3:::site.golobby.xyz/*"
7. 완료 

정책 생성기

 정책 생성기를 통해서 액션, ARN을 이용한 JSON 형태의 정책을 생성한다.

버킷 정책을 설정 한다.

3. 정적 웹 호스팅 설정

  이제 버킷을 만들었다면 여기에 서비스할 리소스를 올려야 한다. 여기서는 테스트 이므로 공식 페이지에 나와 있는 index.html을 수정해서 간단하게 아래와 같은 소스를 업로드 하였다. 

<html> <head> <title>Amazon Route 53 Getting Started</title> </head> <body> <h1>Routing Internet traffic to Cloudfront distributions for your website stored in an S3 bucket</h1> <p>For more information, see <a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started.html">Getting Started with Amazon Route 53</a> in the <emphasis>Amazon Route 53 Developer Guide</emphasis>.</p> </body> </html>

  위의 내용을 index.html 파일로 저장한다음에 아래의 To-Do의 과정을 통해서 업로드 한다.

To-Do

1. site.golobby.xyz 버킷의 상세 화면에서 객체에서 "업로드" 버튼 클릭
2. 사전에 만들어둔 index.html을 선택하고 업로드
3. 업로드가 완료 되면 index.html이 등록됨

  서비스할 페이지를 만들었다면 이제는 정적 웹 호스팅 설정을 통해서 위의 index.html을 외부에서 접근할수 있게 만들어야 한다. 방법은 아래의 To-Do를 참고하여 따라한다.

정적 웹 호스팅 설정 To-Do

1. 버킷의 상세 화면의 "속성" 탭을 선택 최하단에 정적 웹 사이트 호스팅 선택
2. 정적 웹 사이트 호스팅의 활성화 선택, 호스팅 유형은 "정적 웹 사이트 호스팅 선택"
3. 접속시 최초로 보여줄 페이지에 index.html 선택 (에러 페이지가 있을 경우 별도 업로드후 기입)
3. 완료 버튼 클릭이후 별도로 나오는 버킷 웹 사이트 엔드 포인트 확인 
4. http://site.golobby.xyz.s3-website.ap-northeast-2.amazonaws.com 라고 나오고 여기에 접속이 되면 완료

  % 여기까지만 해도 위의 주소를 이용하여 외부에서 정적 홈페이지를 서비스 할 수 있다.

4. 도메인의 등록

  아마존에서도 별도로 도메인을 사용할수 있지만 그럴경우 1년에 몇만원의 비용이 들수 있으니 여기서는 xyz 도메인을 외부에서 등록해서 사용하고자 한다. 요즘 1년에 2천원 정도 사용 가능한 도메인을 쉽게 구할수 있으므로 외부 도메인 등록 기관을 통해서 도메인을 2천원에 등록했다. 

  To-Do

1. 외부 호스팅 업체를 통해서 도메인을 등록 한다.
2. 해당 도메인을 Rote53의 "호스팅 영역" > "호스팅 영역 생성"을 선택하고 기입한다. (그림 1)
3. 생성된 영역에서 나오는 NS 서버 (총 3개 수준)를 등록한 호스팅 업체의 NS로 교체 한다. (그림2)
4. golobby.xyz라고 등록된 도메인을 선택하고 "레코드 생성" 화면으로 진입하여 "단순 레코드 정의"를 선택 (그림3)
5. 여기에 site를 입력하고 레코드 유형은 "A-IPv4주소" 값/트래픽 라우팅 대상은 S3로 존은 서울 리전으로 선택 (그림 3)
6. 마지막으로 S3 엔드 포인트에 s3-website.ap-northeast-2.amazonaws.com 라고 입력 (그림 3) 
    ( 정상적으로 입력이 되었다면 자동으로 스크롤되어 선택할수 있게 해준다. 스크롤이 안된다면 잘못된 것이다.)
7. 이제 레코드를 생성 하여 완료 한다. (그림 4)

해당 도메인을 Rote53의 "호스팅 영역" > "호스팅 영역 생성"을 선택하고 기입한다. (그림 1)
생성된 영역에서 나오는 NS 서버 (총 3개 수준)를 등록한 호스팅 업체의 NS로 교체 한다. (그림2)
golobby.xyz라고 등록된 도메인을 선택하고 "레코드 생성" 화면으로 진입하여 "단순 레코드 정의"를 선택 (그림3)
이제 레코드를 생성 하여 완료 한다. (그림 4)

  이제 모든것이 완료 되었다. 

  % 웹 브라우저에 http://site.golobby.xyz 를 입력해서 아래와 같이 뜬다면 성공한 것이다.  

 

5. 에러가 나올때의 상황

 (1) NoSuchBucket

: Route53의 라우팅 입력시 별도의 값을 입력하지 않는다 즉 site.golobby.xyz.s3-website.ap-northeast-2.amazonaws.com 으로 접속이 가능한 것을 site.golobby.xyz 로 맵핑해주는것이므로 S3 버킷의 이름이 정확하게 등록한 도메인 주소와 일치 하여야 한다. 이럴때에는 버킷의 이름이 라우팅 하고자 하는 도메인으로 정확하게 설정 되었는지 확인한다.

 (2) Access Denied 

Access Denied : S3 버킷에 대한 정책이 입력되지 않은 경우 발생한다. 위의 정책 부분이 빠졌는지 확인한다.

 

6. 정리

 (1) 장점

  - 별도로 웹 서버를 설정할 필요가 없다. (응답 헤더를 봐도 특별한점은 없다.)

요청/응답 헤더

  - 정적으로 리소스를 서비스 해야 할 경우에 당장에 서버의 확장 등을 고려하지 않고도 편리하게 사용 가능하다.
  - 침해에 대한 염려가 적다. (계정이 노출되지 않는다면 별도로 파일을 업로드할 방법은 ? 없는 것 같다. 즉 웹 사이트 디페이스에 어느정도 안정성은 있다 하지만 절대적일지는 ??)
  - 사소하게 신경을 쓰지 않아도 된다. (다만 대량으로 트래픽이 발생된다면 과금이 올라갈 것이다. 주의해야 한다.)

  (2) 주의 할점

   - ACL이나 정책을 별도로 설정하지 않을 경우 모든 파일에 접근이 가능하므로 꼭 노출할 파일만 위치 시킨다.
   - 권한 설정을 했다면 반드시 테스트 해봐야 한다.

 

 

  Go를 개발하는 경우 Import를 통해서 본인이 분리하여 만든 파일을 넣어서 개발하고 싶을수 있다. 
 이때 간단하게 할수 있는 방법에 대해서 알아 보자 

  1. 먼저 프로젝트 폴더 아래에 별도로 폴더를 생성한다.
    아래는 ToolsProject라 폴더 하부에 custompkg 라는 폴더를 생성하였다. 

  그리고 utils.go 파일과 Scanner.go 를 생성 하였다.

 

utils.go
Scanner.go

  package 명은 동일하게 맞추어 준다.

  그리고 main 패키지에서 아래와 같이 호출한다.

main.go

 

모듈이 정상적으로 로드 되었는지 확인한다.

#go mod verify
all modules verified

 이제 go build를 한 다음 실행 파일을 돌려 보면 정상적으로 동작하는것을 볼수 있다.

 

함수

함수는 함수정의 키워드, 함수명, 매개변수, 반환타입의 4가지로 이루어진다

func Attach(data string) string {
     <본문> 
     return result
}

위의 첫째줄을 순서대로 해석하면 아래와 같다.
func : 함수임을 나타낸다
Attach : 함수명
data : 매개변수명
string : 매개변수 타입
string : 반환 타입

리턴은 두가지를 다중 반환 하도록 다중 반환함수를 만들수도 있다.
func Attach(data string) (string, int) 

위와 같은 경우에는 아래처럼 사용하면 된다.
ret, index := Attach(data)

분기문

 

if 문

if 조건문 { 코드 
}else if 조건문 { 코드
} else { 코드
}

예제

if data == "hello" {
fmt.Println("hello") 
} else if data == "bye" {
 fmt.Println("bye")
} else {
 fmt.Println("Good bye")
}

if의 조건문은 && , ||을 이용하여 구성하여 사용한다.
여러개의 조건문을 활용할 경우 괄호를 이용하여 묵어야 한다. 

if문에 초기문과 조건문을 같이 넣기
if rets := tf(true); rets {
if rets := tf(true); rets == true {

위의 문장은 tf 함수에 매개변수로 true를 넣고 함수를 실행한 이후 결과가 true일 때에 if문을 참으로 인식하고 동작하는 초기분을 넣었다. 초기문은 ";" 를 이용하여 넣고 뒷 부분에 매개변수를 통한 조건문이나 조건문을 넣을수 있다.

switch문

switch문은 값에 따라서 수행해야 하는 경우가 틀릴 경우 사용함

    switch data {
    case "hello":
        fmt.Println("hello")
    case "bye":
        fmt.Println("bye")
    default:
        fmt.Println("Good Bye")
    }

다양한 사용법이 존재함
다중 조건 case 사용
 case "hello", "bye":

조건문을 이용한 case 문을 사용
case degree > 5:

초기값을 이용하여 함수를 호출한 이후 사용
    switch rets := tf(false); rets {
    case true:
        fmt.Println("hello")

for문

for문은 조건을 가진 반복 작업에 사용
for 초기화; 조건문; 증가자 {
  <코드>
}

예제
for a := 0; a < 10; a++ {
  fmt.Print(a)

continue와 break를 이용하여 구성 가능함

 

데이터 다루기

배열

배열은 같은 데이터 타입으로 이루어진 값들의 묶음

선언

var 변수명 [사이즈]타입
var data [100]string

초기화 및 데이터 입력

    var data3 [5]string = [5]string{"haha", "hihi", "huhu"}
    초기화 하면서 같은 사이즈의 배열을 할당

    data3[3] = "hoho"
    비어있는 3번에 데이터 입력

출력 방식
    for i, a := range data3 {
        fmt.Println(i, a)
    }

range를 이용하여 들어간 배열 만큼 동작 하다록 함
자바나 타 언어와 동일하게 다중 배열 사용 가능함

구조체

  구조체는 C에서 자주 사용하던 것과 거의 유사하게 사용할 수 있게 된 데이터들의 집합이다. 

선언
type <구조체명> struct {
  필드명  데이터타입
  필드명  데이터타입
}

위와 같이 선언하여 사용 할수 있다.
그럼 실제로 구조체를 선언하여 사용해 보자

type Member  struct {
  UserID string
  UserNo int
  Name string
  Address string
}

func main() {
  var member Member
  member.Address = "부산시...."

    fmt.Println(member.Address)
}

 

만약 구조체 배열 즉 slice를 만든 다음에 해당 구조체에 값을 추가 하고자 할 경우에는 아래와 같다.

 

var member2 []Member
member := Member{"guest", 1213, "김수로", "경기도"}
member2 = append(member2, member)

위에서 정의한 Member가 할당된 member에 값을 할당한 다음 이를 member2 슬라이스에 append 하면 되는 구 조이다. 
 실제로 자바와 유사함

  

참고자료

GO 언어의 표준 패키지 검색

https://golang.org/pkg

 

Standard library - pkg.go.dev

Directories ¶ Expand all tar Package tar implements access to tar archives. Package tar implements access to tar archives. zip Package zip provides support for reading and writing ZIP archives. Package zip provides support for reading and writing ZIP arch

pkg.go.dev

 
 
외부 패키지 검색

https://github.com/avelino/awesome-go

 

GitHub - avelino/awesome-go: A curated list of awesome Go frameworks, libraries and software

A curated list of awesome Go frameworks, libraries and software - GitHub - avelino/awesome-go: A curated list of awesome Go frameworks, libraries and software

github.com

 

go.modGo 1.11부터 go 명령은 디렉토리가 외부 에 있는 경우 현재 디렉토리 또는 상위 디렉토리에 a가 있는 경우 모듈을 사용할 수 있도록 합니다 

+ Recent posts