기존에 Cognito를 이용해서 Kibana의 접근을 제한해왔었다.

기존에는 단순히 kibana 접근만 제한하고 있어서 audit 통과가 목적이었지만

운영하다보니 Role을 부여해서 세세하게 접근을 제한하고 싶어졌다.

Elasticsearch의 index단위로 접근을 제한하고 read/write 권한 조절하기 위하여

Opendistro를 이용하기로 했다.

 

Elasticsearch 설치형에서는 이미 사용중이었고

AWS의 ElasticSearch에 지원을 한지 좀 되었지만.. 이제 반영하려한다.

 

Launching Open Distro for Elasticsearch security features on Amazon Elasticsearch Service | Amazon Web Services

We are excited to announce that we are making new Open Distro for Elasticsearch security features available on Amazon Elasticsearch Service. Amazon Elasticsearch Service is frequently used for sensitive enterprise workloads, and today’s launch adds multi

aws.amazon.com

 

Open Distro의 API가 있겠거니하고 문서를 찾아본다.

 

API

Documentation for Open Distro for Elasticsearch, the community-driven, 100% open source distribution of Elasticsearch with advanced security, alerting, deep performance analysis, and more.

opendistro.github.io


Account Create 요청이다.

#### REQUEST

PUT _opendistro/_security/api/internalusers/<username>
{
  "password": "kirkpass",
  "backend_roles": ["captains", "starfleet"],
  "attributes": {
    "attribute1": "value1",
    "attribute2": "value2"
  }
}

 

backend role 대신에 일반 role을 맵팽하는 방식을 사용할 것이고,

attributes 정보는 아직은 안쓸것이라서 

password만 사용할 예정이다. (이것도 default pw로 처음 로그인할때 알아서 바꾸게 해줄 방법은 없으려나..)

 

1차로 구현했던 코드

아래의 내용은 본인 환경에 맞게 전부 수정해서 사용해야 한다.

 

참고로 opendistro_admin, opendistro_admin_pw는 실제 admin 계정의 것을 사용하거나, 계정관련 security menu 접근 권한이 있는 계정의 정보를 이용한다.

import json
import requests

def opendistro_create_user():
    user_name = 'testuser'
    base_url = 'https://vpc-sfixer-applog-jdqfbp4ttozpwfxxxxxxxxxxxx.ap-eastsouth-1.es.amazonaws.com/'
    path = '_opendistro/_security/api/internalusers/%s' % (user_name)
    url = base_url + path
    payload = {'password': 'INITpassword1234!@#$', 'backend_roles': ['read_write_all_index']}
    rs = requests.put(url, auth=('opendistro_admin', 'opendistro_admin_pw'), data=payload)
    print(rs.content)

매뉴얼에 나와있는대로 PUT을 수행했다.

결과는 에러

b'{"error":"Content-Type header is missing","status":406}'

해더를 빼먹었으니 넣어준다.

 

2차로 구현한 코드

import json
import requests

def opendistro_create_user():
    user_name = 'testuser'
    base_url = 'https://vpc-sfixer-applog-jdqfbp4ttozpwfxxxxxxxxxxxx.ap-eastsouth-1.es.amazonaws.com/'
    path = '_opendistro/_security/api/internalusers/%s' % (user_name)
    url = base_url + path
    headers = {'content-type': 'application/json'}
    payload = {'password': 'INITpassword1234!@#$', 'backend_roles': ['read_write_all_index']}
    rs = requests.put(url, auth=('opendistro_admin', 'opendistro_admin_pw'), data=payload, headers=headers)
    print(rs.content)

결과는 다시 에러

b'{"status":"error","reason":"Could not parse content of request."}'

data type이 문제로 보인다.

 

requests.put 할때 파라메터를 수정해주는데, 해결방안이 2개가 있다. 

  1. data=json.dumps(payload)
  2. json=payload

2안을 택했다.

3차로 구현한 코드 [성공]

import json
import requests

def opendistro_create_user():
    user_name = 'testuser'
    base_url = 'https://vpc-sfixer-applog-jdqfbp4ttozpwfxxxxxxxxxxxx.ap-eastsouth-1.es.amazonaws.com/'
    path = '_opendistro/_security/api/internalusers/%s' % (user_name)
    url = base_url + path
    headers = {'content-type': 'application/json'}
    payload = {'password': 'INITpassword1234!@#$', 'backend_roles': ['read_write_all_index']}
    rs = requests.put(url, auth=('opendistro_admin', 'opendistro_admin_pw'), json=payload, headers=headers)
    print(rs.content)

결과는 성공이다.

b'{"status":"CREATED","message":"\'testuser\' created."}'

 

Role Mapping 관련해서는 

mapping 해주거나 backend_role을 사용하도록 해야한다.

다른 동료들이 나중에 Kibana에서 보고 처리하기 쉬울것 같아서 mapping 해주는 방식을 선택하였다.

#### REQUEST

PUT _opendistro/_security/api/rolesmapping/<role>
{
  "backend_roles" : [ "starfleet", "captains", "defectors", "cn=ldaprole,ou=groups,dc=example,dc=com" ],
  "hosts" : [ "*.starfleetintranet.com" ],
  "users" : [ "worf" ]
}

여기에서 나는 role만 매핑할거라서 사용하게될 정보는 users만 사용한다.

그리고 미리 role을 kibana에서 생성해두고 그것을 사용한다.

 

1차 시도한 코드

import json
import requests

   
def opendistro_mapping_role(user_name, role_name='read_write_limit'):
    base_url = 'https://vpc-sfixer-applog-jdqfbp4ttozpwfxxxxxxxxxxxx.ap-eastsouth-1.es.amazonaws.com/'
    path = '_opendistro/_security/api/rolesmapping/%s' % (role_name)
    url = base_url + path
    headers = {'content-type': 'application/json'}
    payload = {'users': [user_name]}
    rs = requests.put(url, auth=('opendistro_admin', 'opendistro_admin_pw'), headers=headers, json=payload)
    print(rs.content)

돌려보니 되는줄 알았다.

문제는 users라고 되어있는것을 제대로 파악 못한것이 문제.

이런식으로 루프 돌려가면서 호출했더니 가장 마지막에 호출한 user 정보 1개만 남았다.

for user in user_list:

    opendistro_mapping_role(user)

 

 2차 시도한 코드는 원하는대로 동작 [성공]

import json
import requests

   
def opendistro_mapping_role(user_list, role_name='read_write_limit'):
    base_url = 'https://vpc-sfixer-applog-jdqfbp4ttozpwfxxxxxxxxxxxx.ap-eastsouth-1.es.amazonaws.com/'
    path = '_opendistro/_security/api/rolesmapping/%s' % (role_name)
    url = base_url + path
    headers = {'content-type': 'application/json'}
    payload = {'users': user_list}
    rs = requests.put(url, auth=('opendistro_admin', 'opendistro_admin_pw'), headers=headers, json=payload)
    print(rs.content)

1차에서 개별 사용자를 처리하려고 loop 돌렸던 것을 없애고 

그 사용자 list를 인자값으로 넘겼더니 제대로 mapping 된것을 kibana에서 확인하였다.

사용자 list라함은 이런 형태로 값이 저장되어있다.

  • user_list = ['user1', 'user2', 'user3', ... , ... , 'user100']

 

 

'Infra' 카테고리의 다른 글

Python으로 Opendistro Account 생성하기  (0) 2021.03.17
Cloudfront와 S3를 이용한 웹 서비스 구성  (0) 2021.03.10
Hashicorp Terraform (테라폼)  (0) 2020.10.28
AWS Subnet 생성하기  (0) 2020.07.23
AWS VPC 생성하기  (0) 2020.07.23
AWS EKS Service Role 생성 (IAM)  (0) 2020.07.23

 

Web service를 시작하기로 하였다.

CDN을 둬서 static contents들을 서빙하려하고 cloudfront를 사용하기로 결정하였다.

Data의 보관은 S3 bucket에 static contents를 두고 cloudfront에서 접근해서 가져가는 방식을 사용하기로 결정하였다.

 

기본 세팅

S3, Cloudfront, Route53 관련 세팅하는 것은 하나씩 읽어가면서 누르면 된다. 검색하면 포스팅한 글이 이미 많다.

개인적으로는 각 설정 항목에 대한 설정은 한번 자세히 보고 넘어야가야 한다는 생각이다.

혹은 cloudformation 템플릿을 이용해서 구성한다. 

CloudFront와 S3를 이용해서 서빙을 한다면 처음 세팅할때 이 부분을 반드시 "Yes"로 해주고 Identity는 Access S3 bucket content only through CloudFront를 선택한다.

만약 No로 한 경우에는 나중에 Origin 설정에서 바꾸려고 해도 바꿀수는 없고, Origin을 삭제하고 다시 만드는 방법이 있을 수 있겠다.

HTTPS로만 접근을 허용하겠지만
그렇다고 HTTP 요청을 다 버리고 싶진 않으니 Redirect 하도록 Behavior에서 설정해주었다.

 

TTL

TTL 설정을 통한 cache 전략에서 고민이 시작되었다.

평소에는 static 파일들을 추가만 할테니 TTL을 aws에서 default로 제공하는 것을 그냥 사용해도 아무런 문제가 없다.

문제는 hotfix. 

배포된 이미지 파일의 구문이 잘 못되서 급히 변경해야 되는 상황 같은 경우.

물론 Invalidations 기능이 있어서 긴급할때는 이 기능을 이용해서 cache를 다 날려버릴 수 있다.

AWS console에서 눌러가면서 하거나

 

아니면 awscli로 처리한다.

# sample

aws cloudfront create-invalidation --distribution-id $distribution_ID --paths "/*"

 

다시 TTL 설정으로 돌아와서 3개의 TTL 의미 파악을 못했다.

물론 HTTP Header에 Cache-Control: max-age=xx, Cache-Control: s-maxage=xx 같은 값이 없으면 default TTL인 것은 알겠으나, 
minimum TTL, maximum TTL 관련해서는 이 메뉴얼을 읽어보았지만 이해를 못했었다.

  • default TTL (Cache-Control, Expires header가 없는 경우)
  • minimum TTL
  • maximum TTL

 

그러던중에 이를 이해할 수 있게 정리한 포스팅을 찾았다.

  • 만약 Cache-Control 헤더의 max-age 값이 사용자가 정의한 minimum TTL과 maximum TTL 사이에 있는 경우, CloudFront는 maximum TTL에 지정된 시간에 대해 개체를 캐시합니다.
  • 만약 max-age 값이 사용자가 정의한 minimum TTL보다 작으면 CloudFront는 minimum TTL값에 대해 개체를 캐시합니다.
  • 만약 max-age 값이 사용자가 정의한 maximum TTL보다 큰 경우 CloudFront는 maximum TTL 값에 대해 개체를 캐시합니다.

대충 이해가 간다.

Cache-Contorl, Expires 해더를 이용해서 세팅을 해주면 TTL을 내가 원하는대로 맞춰서 사용할 수 있다는 것은 알겠다.

 

그럼 다시 Cloudfront로 돌아와서 Cache policies 중에 "Managed-CachingOptimized"의 TTL 세팅을 다시 본다.

  • Minimum TTL: 1 sec
  • Maximum TTL: 31536000 sec (1 year)
  • Default TTL: 86400 sec (1 day)

어떤 설정인지는 알겠는데 좀 더 확실하게 알아야겠다고 생각하고 메뉴얼을 다시 읽어 보았다.

AWS는 뉴얼을 잘 봐야하는 걸 알면서도 제대로 안보고 지나쳤던것이 문제였다.

이제서야 메뉴얼이 눈에 들어오기 시작한다.

메뉴얼을 자세히 보면 이해가 되겠지만 다시한번 적어보면서 이해를 해본다.

  • minimum TTL은 Min TTL, maximum TTL은 Max TTL로 표현한다.

표에 나오는 HTTP header

  • Cache-Control: max-age=<seconds>  (e.g. Cache-Control: max-age=1200)
  • Cache-Control: s-maxage=<seconds> (e.g. Cache-Control: s-maxage=1200)
  • Expires: <http-date> (e.g. Expires: Wed, 10 Mar 2021 07:28:00 GMT)
Origin 해더 Min TTL = 0 sec Min TTL > 0 sec (1초 보다 큼)
Origin object에
Cache-Control: max-age
헤더 추가
[CloudFront 캐싱]
Cloudfront는
Cache-Control max-age와 Max TTL의 값 중
더 작은 값 동안 캐싱


[Browser 캐싱]
Browser는
Cache-Control max-age 동안 캐싱

[CloudFront 캐싱]
Cloudfront는
Min TTL < max-age < Max TTL

- Cache-Control max-age 동안 캐싱
max-age < Min TTL
- Min TTL 동안 캐싱
max-age > Max TTL
- Max TTL 동안 캐싱

[Browser 캐싱]
Browser는
Cache-Control max-age 동안 캐싱

Origin object에
Cache-Control: max-age
헤더 추가 안함
[CloudFront 캐싱]
Cloudfront는 
default TTL
 동안 캐싱

[Browser 캐싱]
Browser 마다 다름
[CloudFront 캐싱]
Cloudfront는
Min TTL과 default TTL 둘중 더 값이 큰 값 동안 캐싱

[Browser 캐싱]
Browser 마다 다름
Origin object에
Cache-Control: max-age와
Cache-Control: s-maxage
헤더 추가 
[CloudFront 캐싱]
Cloudfront는 
Cache-Control s-maxage와 Max
 TTL의 값 중
더 작은 값 동안 캐싱


[Browser 캐싱]
Cache-Control max-age 동안 캐싱
[CloudFront 캐싱]
Cloudfront는
Min TTL < s-maxage < Max TTL

- Cache-Control s-maxage 동안 캐싱
s-maxage < Min TTL
- Min TTL 동안 캐싱
s-maxage > Max TTL
- Max TTL 동안 캐싱

[Browser 캐싱]
Browser는
Cache-Control max-age 동안 캐싱
Origin object에
Expires 헤더 추가
[CloudFront 캐싱]
Cloudfront는 
Expires의 날짜와 Max
 TTL의 값 중
더 빨리 만료되는 동안 객체를 캐싱


[Browser 캐싱]
Browser는
Expires의 날짜와 시간 까지 캐싱
[CloudFront 캐싱]
Cloudfront는
Min TTL < Expires < Max TTL

- Expires의 날짜와 시간 까지 캐싱
Expires < Min TTL
- Min TTL 동안 캐싱
Expires > Max TTL
- Max TTL 동안 캐싱

[Browser 캐싱]
Browser는
Expires의 날짜와 시간 까지 캐싱
Origin object에
Cache-Control: no-cache, no-store
혹은 private 
헤더 추가
CloudFront, Broser는 헤더의 설정에 따른다.

CloudFront에서 Cache-Control: no-cache 처리방식은 링크 참고
[CloudFront 캐싱]
Cloudfront는 Min TTL 동안 캐싱

[Browser 캐싱]
Browser 헤더의 설정을 따름

 

 

다음으로는 나의 static file들이 S3에 있으니 S3에 object 세팅을 해줘야 할 것 같다.

S3 object에 Metadata을 이용하면 되겠다.

일단 그럼 테스트를 한번 해본다.

테스트라서 빌드 디렉터리를 통째로 옵션을 줬지만,, 실제로는 파일 확장자 단위로 하거나 좀 더 잘게 나눠서 할 예정이다.

(react app 만들고 빌드할 설정과 aws s3 sync할 설정에 대한 설명은 제외,, 다른 방법으로도 테스트는 가능하므로)

> create-react-app sample-deploy
...
...

> cd sample-deploy
> yarn build
...
...

> aws s3 sync ./build s3://test-upload-bucket --metadata='{"Cache-Control":"max-age=300"}'
...
...

원하는대로 metadata가 세팅이 되었는지 확인해본다.

 

Value는 내가 원하는대로 올라갔는데 Key 값이 다르다.

"x-amz-meta-"로 시작하는 헤더는 User defined(사용자 정의) 메타데이터 HTTP 헤더로 별도로 구분하기 위한 키워드인데 이것은 원래 하려던것이 아니다.

 

다른 옵션을 찾아서 옵션을 바꿔보았다. '--cache-control' 로 해보니 원하는대로 Key, Value가 세팅되었다.

> aws s3 sync ./build s3://test-upload-bucket -cache-control max-age=1200
...
...

 

S3 Object 접근 제한

외부에서 S3 Object에 직접적인 접근은 제한을 걸고 싶다.

그래서 크게 2개의 접근만 허용해주고 나머지는 제한하려고 했다.

  • 업무하는 사무실의 접근
  • CloudFront의 접근

사무실에서의 접근은 가장 편하고 직관적인 IP 허용으로 처리했다.

CloudFront에서의 접근은 Origin Access Identity를 이용해서 허용해주었다. (ColudFront의 Origin 설정에서 확인)

 

S3의 Bucket에서 Permission 탭에 있는 Bucket policy 세팅 결과이다.

주요 정보들은 x, y 같은 것으로 바꿔두었다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::test-upload-bucket/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "x.x.x.x/32",
                        "y.y.y.y/32"
                    ]
                }
            }
        },
        {
            "Sid": "CloudfrontOAI",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E2ZZZ2IRJXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::test-upload-bucket/*"
        }
    ]
}

테스트를 해본다.

wifi를 끈 휴대폰을 이용해서 S3 url에 직접 접근해았더니 Access Denied 발생한다.

Cloudfront에 접근해서 보니 잘 보인다.

참고로 Route53에 dns 세팅을 미리 해두었고 그것을 Alternative Domain Names(CNAMEs)에 추가해서 이용하였다. 

이 부분은 마우스 클릭 몇번이면 되므로 패스.

 

나머지는 운용해나가면서 적절히 맞춰가야겠는데

Behaviors에서 Path Pattern 적용해서 Cache policy 적용해주는것 (개발팀과 협의 (modify없이 add만)? 배포할때마다 버저닝?)

Error Pages에서 에러 발생에 대한 응답 페이지/코드 세팅해주는 정도를 추가로 맞추게 되지 않을까 싶다.

거기에 Origin이 늘어나면 거기에 따른 추가 설정들도..

'Infra' 카테고리의 다른 글

Python으로 Opendistro Account 생성하기  (0) 2021.03.17
Cloudfront와 S3를 이용한 웹 서비스 구성  (0) 2021.03.10
Hashicorp Terraform (테라폼)  (0) 2020.10.28
AWS Subnet 생성하기  (0) 2020.07.23
AWS VPC 생성하기  (0) 2020.07.23
AWS EKS Service Role 생성 (IAM)  (0) 2020.07.23

Terraform

[ 사전적 의믜 ]

Terraforming(테라포밍)은 지구가 아닌 다른 행성 및 위성, 기타 천체의 환경을 지구의 대기 및 온도 생태계와 비슷하게 바꾸어 인간이 살 수 있도록 만드는 작업으로 화성탐사 관련해서 종종 등장하는 용어입니다.

하시코프에서 이 제품의 이름을 왜 이렇게 지었을지 생각해보았습니다.

단어 뜻에서 각기 다른 모든 vendor의 인프라 환경을 비슷하게 바꾸어 서비스를 할 수 있도록 만드는 작업을 하는 도구라고 느껴집니다.

 

[ 특징 ]

테라폼은 Chef, Puppet, 과 같이 Infrastructure provisioning 툴로 분류할 수 있습니다.

source: http://blog.shippable.com/the-future-of-devops-is-assembly-lines

The key features of Terraform are:

  • Infrastructure as Code: Infrastructure is described using a high-level configuration syntax. This allows a blueprint of your datacenter to be versioned and treated as you would any other code. Additionally, infrastructure can be shared and re-used.  👉 버전으로 인프라 이력관리, 인프라 공유 및 재사용

  • Execution Plans: Terraform has a "planning" step where it generates an execution plan. The execution plan shows what Terraform will do when you call apply. This lets you avoid any surprises when Terraform manipulates infrastructure. 
    👉 plan 단계를 거치면서 인프라에 어떤 변화가 생길지 볼 수 있음

  • Resource Graph: Terraform builds a graph of all your resources, and parallelizes the creation and modification of any non-dependent resources. Because of this, Terraform builds infrastructure as efficiently as possible, and operators get insight into dependencies in their infrastructure. 👉 모든 리소스를 그래프로 작성하고 종속되지 않은 리소스의 추가와 변경을 병렬로 처리해서 효율적으로 인프라를 구축하고 각 리소스의 의존성을 확인 할 수 있음

source: https://www.terraform.io/docs/commands/graph.html

  • Change Automation: Complex changesets can be applied to your infrastructure with minimal human interaction. With the previously mentioned execution plan and resource graph, you know exactly what Terraform will change and in what order, avoiding many possible human errors. 👉 terraform plan, 그 결과로 나오는 resource graph로 어떤 순서로 변경이 발생할지 미리 확인할 수 있어서 휴먼에러를 많이 줄일 수 있음

 

[ 버전 관리 ]

다른 패키지와 마찬가지로 일정 시간이 지나면 new feature, bug fix등의 작업으로 upgrade 될것이고 그에 따라 맞춰주는 작업이 필요해집니다. 시간이 지나면 버전관리할 필요가 생기게 되는데 이때 크게 2가지 방법을 사용할 수 있습니다.

[ Use cases ]

이중에서 제가 Terraform을 선택하려는 이유는

  • Heroku App setup  : -
  • Multi-Tier Applications : API 서버, 캐싱 서버등 추가되는 레이어를 개별적으로 확장
  • Self-Service Clusters : 서비스 구축과 확장한 방법들을 코드화
  • Software Demos : -
  • Disposable Environments : 서비스에 따라서 Dev, Stage 환경을 빠르게 구성해주었다가 폐기
  • Software Defined Networking : AWS VPC 부터 네트워크 구성을 코드화
  • Resource Schedulers : -
  • Multi-Cloud Deployment : 관리를 단순화 시켜 대규모 멀티 클라우드 인프라 용이

 

 

'Infra' 카테고리의 다른 글

Python으로 Opendistro Account 생성하기  (0) 2021.03.17
Cloudfront와 S3를 이용한 웹 서비스 구성  (0) 2021.03.10
Hashicorp Terraform (테라폼)  (0) 2020.10.28
AWS Subnet 생성하기  (0) 2020.07.23
AWS VPC 생성하기  (0) 2020.07.23
AWS EKS Service Role 생성 (IAM)  (0) 2020.07.23

안녕하세요 쿤드입니다. 🍀

이번엔 Subnet을 생성해보려고 합니다.

 

제가 사용하는 리전에는 Availability Zone이 3개가 있긴한데 

2개의 Zone만 사용해서 private용 2개, public용 2개 총 4개를 생성했습니다.

 

IPv4 CIDR block으로 IP 범위를 지정해주었는데

각 서브넷당 최대 4094개의 host를 할당 해 줄 수 있도록 netmask는 20으로 설정했습니다.

  • 10.3.0.0/20 (10.3.0.1 ~ 10.3.15.254)
  • 10.3.16.0/20 (10.3.16.1 ~ 10.3.31.254)
  • 10.3.32.0/20 (10.3.32.1 ~ 10.3.47.254)
  • 10.3.48.0/20 (10.3.48.1 ~ 10.3.63.254)

Subnet을 생성하고 나면 각 서브넷마다 할당할 수 있는 IP 주소 여분의 개수도 확인할 수 있습니다.

 

서브넷을 세팅하고 나면 Route Table을 설정합니다. 

 

클릭하고 들어간 후에 할당해줄 subnet을 선택하고 서로 Associate시켜 줍니다.

 

 

그리고 나머지 Route Table은 필요한 경우에 Edit routes를 이용해서 정보를 추가해줍니다.

 

 

IPSec VPN을 이용해서 네트웍 설정을 한 경우에는 위의 메뉴에서 직접 설정이 불가능했었습니다.

저 같은 경우에는 자체 설정한 Site-to-Site VPN 설정, 직접 구축한 OpenVPN에 대한 라우팅 설정을 할때 직접 추가 했었습니다.

 

 

나머지 작업은

Public으로 사용하기 위한 subnet에서 사용할 Internet Gateway

Private으로 사용하기 위한 subnet에서 사용할 NAT Gateway

  • 참고로 NAT Gateway 생성할 때는 여기에서 사용할 때는 Associate Elastic IP address를 클릭하면 알아서 EIP를 생성해서 할당해줍니다.
  • NAT Gateway를 삭제 혹은 이미 Associate Elastic IP address를 클릭하고 NAT Gateway 생성을 취소한 경우 EIP가 이미 생성되어 있으므로 release 시켜서 불필요한 비용 발생하지 않도록 합니다.

설정만 해주면 기본적인 VPC 구성은 되었다고 볼 수 있습니다.

'Infra' 카테고리의 다른 글

Cloudfront와 S3를 이용한 웹 서비스 구성  (0) 2021.03.10
Hashicorp Terraform (테라폼)  (0) 2020.10.28
AWS Subnet 생성하기  (0) 2020.07.23
AWS VPC 생성하기  (0) 2020.07.23
AWS EKS Service Role 생성 (IAM)  (0) 2020.07.23
AWS EKS Cluster 세팅  (0) 2020.07.23

안녕하세요 쿤드입니다. 🍀 

이번엔 VPC 생성하는 방식에 대해서 확인해보겠습니다.

 

AWS VPC

  • Virual Private Cloud
  • AWS 사용자가 정의한 전용 가상 네트워크입니다.

 

생성하기

  • 적절한 이름을 입력하고
  • VPC에서 사용할 IP 주소의 범위를 정합니다.
  • 저는 IPv6는 사용하지 않아서 default인 No IPv6 CIDR Block을 선택했습니다.
  • Tenancy
    • default : 인스턴스가 공유된 하드웨어에서 실행
    • dedicated : 인스턴스가 단일 테넌트 하드웨어에서 실행

 

 

VPC를 생성하고 나면 통신을 위해서

Subnet을 세팅합니다.

'Infra' 카테고리의 다른 글

Hashicorp Terraform (테라폼)  (0) 2020.10.28
AWS Subnet 생성하기  (0) 2020.07.23
AWS VPC 생성하기  (0) 2020.07.23
AWS EKS Service Role 생성 (IAM)  (0) 2020.07.23
AWS EKS Cluster 세팅  (0) 2020.07.23
S3에 SQS notification event 추가할때 권한 설정  (0) 2020.06.26

안녕하세요 쿤드입니다. 🍀

 

AWS IAM (Identity and Access Management)은

  • AWS Identity and Access Management(IAM)는 AWS 리소스에 대한 액세스를 안전하게 제어할 수 있는 웹 서비스입니다.
  • IAM을 사용하여 리소스를 사용하도록 인증(로그인) 및 권한 부여(권한 있음)된 대상을 제어합니다.

Step 1. EKS Cluster용 Role 생성

  • EKS 선택

 

 

  • EKS - Cluster 선택

 

  • 적절히 Tag 설정
  • Role 관련 name 및 description 세팅 

 

  • Create role 하면 Role이 생성됩니다.
  • 이후에는 EKS 메뉴로 가서 Cluster Service Role의 refresh 버튼을 누르면 보이게 되고 선택해주면 됩니다. 

 

이 Role에 추가한 policy를 확인해보겠습니다.

AmazonEKSClusterPolicy(AWS Managed policy)는 4개 서비스의 권한과 1개의 IAM 인증 권한을 허용합니다.

  • AutoScaling
  • EC2
  • ELB
  • KMS
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:UpdateAutoScalingGroup",
                
                "ec2:AttachVolume",
                "ec2:AuthorizeSecurityGroupIngress",
                
                "ec2:CreateRoute",
                "ec2:CreateSecurityGroup",
                "ec2:CreateTags",
                "ec2:CreateVolume",
                
                "ec2:DeleteRoute",
                "ec2:DeleteSecurityGroup",
                "ec2:DeleteVolume",
                
                "ec2:DescribeInstances",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVolumes",
                "ec2:DescribeVolumesModifications",
                "ec2:DescribeVpcs",
                "ec2:DescribeDhcpOptions",
                "ec2:DescribeNetworkInterfaces",
                
                "ec2:DetachVolume",
                
                "ec2:ModifyInstanceAttribute",
                "ec2:ModifyVolume",
                
                "ec2:RevokeSecurityGroupIngress",
                
                "elasticloadbalancing:AddTags",
                "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
                "elasticloadbalancing:AttachLoadBalancerToSubnets",
                
                "elasticloadbalancing:ConfigureHealthCheck",
                
                "elasticloadbalancing:CreateListener",
                "elasticloadbalancing:CreateLoadBalancer",
                "elasticloadbalancing:CreateLoadBalancerListeners",
                "elasticloadbalancing:CreateLoadBalancerPolicy",
                "elasticloadbalancing:CreateTargetGroup",
                
                "elasticloadbalancing:DeleteListener",
                "elasticloadbalancing:DeleteLoadBalancer",
                "elasticloadbalancing:DeleteLoadBalancerListeners",
                "elasticloadbalancing:DeleteTargetGroup",
                
                "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                "elasticloadbalancing:DeregisterTargets",
                
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeLoadBalancerAttributes",
                "elasticloadbalancing:DescribeLoadBalancerPolicies",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroupAttributes",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeTargetHealth",
                
                "elasticloadbalancing:DetachLoadBalancerFromSubnets",
                
                "elasticloadbalancing:ModifyListener",
                "elasticloadbalancing:ModifyLoadBalancerAttributes",
                "elasticloadbalancing:ModifyTargetGroup",
                "elasticloadbalancing:ModifyTargetGroupAttributes",
                
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "elasticloadbalancing:RegisterTargets",
                
                "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer",
                "elasticloadbalancing:SetLoadBalancerPoliciesOfListener",
                
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
                }
            }
        }
    ]
}

'Infra' 카테고리의 다른 글

AWS Subnet 생성하기  (0) 2020.07.23
AWS VPC 생성하기  (0) 2020.07.23
AWS EKS Service Role 생성 (IAM)  (0) 2020.07.23
AWS EKS Cluster 세팅  (0) 2020.07.23
S3에 SQS notification event 추가할때 권한 설정  (0) 2020.06.26
AWS의 Cloudwatch와 CloudTrail의 차이  (0) 2020.06.01

안녕하세요 쿤드입니다. 🍀 

이번엔 EKS Cluster를 생성해 보겠습니다.

 

Amazon EKS

  • Amazon EKS는 Kubernetes의 Control Plain or Node를 설치, 운영 및 유지보수 할 필요 없이 AWS에서 Kubernetes를 손쉽게 실행할 수 있는 관리형 서비스입니다.
    • Kubernetes는 컨테이너화된 애플리케이션의 배포, 조정 및 관리 자동화를 위한 오픈 소스 시스템입니다.

 

구축하기

Step 1. 클러스터 설정 (Configure cluster)

  • Name과 version을 선택합니다.
  • Cluster Service로 사용할 IAM role을 미리 생성해두고 선택합니다.
  • Tag는 적절하게 추가합니다. (나중에 관리 및 비용 구분하기 용이하도록)

 

Step 2. 네트워킹 설정 (Specify networking)

VPC(Virtual Private Cloud) 선택

  • 원하는 VPC를 선택합니다.
  • 필요한 경우 새로운 VPC를 생성합니다.

 

Subnet 선택

  • EKS 클러스터를 생성할때는 2개 이상의 서브넷이 필요합니다.
  • 물론 1개의 subnet에 public, private으로 구분할 수도 있는데 그렇게 2개 서브넷을 선택한 경우에는 이런 에러가 발생합니다.

  • 노드를 위치시킬 VPC를 기존 사용하던 곳에 할지 완전히 분리하도록 새로운 VPC를 생성할지 결정한 후에 선택합니다.
  • Endpoint Access 인 경우는 Private으로 설정하면 local pc에서 kubectl 설정하여 접근할때 아래의 문제로 인해서 추가적인 네트웍 설정이 필요합니다.
    • Unable to connect to the server: dial tcp 172.xx.xxx.xx:443: i/o timeout

 

 

나머지는 로깅 할지 여부 설정, 그리고 review 이후에 생성하면 됩니다.

'Infra' 카테고리의 다른 글

AWS VPC 생성하기  (0) 2020.07.23
AWS EKS Service Role 생성 (IAM)  (0) 2020.07.23
AWS EKS Cluster 세팅  (0) 2020.07.23
S3에 SQS notification event 추가할때 권한 설정  (0) 2020.06.26
AWS의 Cloudwatch와 CloudTrail의 차이  (0) 2020.06.01
Route53 DNS health check (for Nginx)  (0) 2019.12.20

안녕하세요 쿤드입니다. 🍀

S3 버킷에서 어떤 object가 생성되면 그에 대한 이벤트를 SQS로 받아서 처리할 필요가 생겼습니다.

설정대로 맞춰놓고 생성을 했는데 

  • [버킷] - [Properties] - Advenced settings [Events] 

에러가 발생합니다.

S3 이벤트 세팅

에러메시지

Unable to validate the following destination configurations. Permissions on the destination queue do not allow S3 to publish notifications from this bucket. (arn:aws:sqs:REGION:AWS계정ID:세팅하려던_SQS_QUEUE_NAME)

 

최초 생성은 IAM role로 접근에 제한을 둔 account로 생성하다가 실패해서 단순히 account에 권한이 없어서 안되는줄 알았습니다.

그래서 ADMIN 권한 (* 접근)을 가진 account로 다시 생성을 했는데 

마찬가지로 에러가 발생합니다.

 

이제서야 AWS 문서를 찾아서 읽어봤습니다.

https://docs.aws.amazon.com/AmazonS3/latest/dev/ways-to-add-notification-config-to-bucket.html 

 

Walkthrough: Configure a bucket for notifications (SNS topic and SQS queue) - Amazon Simple Storage Service

Walkthrough: Configure a bucket for notifications (SNS topic and SQS queue) Walkthrough summary In this example, you add a notification configuration on a bucket requesting Amazon S3 to do the following: Publish events of the s3:ObjectCreated:* type to an

docs.aws.amazon.com

읽어보니

SNS를 추가하면 SNS topic에 권한을 설정해주고

SQS를 추가하는 거라면 마찬가지로 SQS Queue에 권한을 추가하라는 말이었습니다.

 

남은 작업은

이제 정확하게 권한을 추가해주면 되는데 

{
 "Version": "2012-10-17",
 "Id": "example-ID",
 "Statement": [
  {
   "Sid": "example-statement-ID",
   "Effect": "Allow",
   "Principal": {
    "AWS":"*"  
   },
   "Action": [
    "SQS:SendMessage"
   ],
   "Resource": "SQS-queue-ARN",
   "Condition": {
      "ArnLike": { "aws:SourceArn": "arn:aws:s3:*:*:bucket-name" },
      "StringEquals": { "aws:SourceAccount": "bucket-owner-account-id" }
   }
  }
 ]
}

이게 뭐지? (라고 처음엔 느껴졌지만 작업을 마무리하고 다시 읽어보니 이해가 갑니다.)

 

일단 stackoverflow에서 비슷한 문제를 찾았습니다.

 stackoverflow.com/q/54791704/8163714

 

Unable to configure SQS queue notification in S3

I created an SQS queue and added policy under permission tab allowing only my account users to configure the configure the notification Policy Document { "Version": "2012-10-17", "Id": "arn:...

stackoverflow.com

들여쓰기의 차이일 뿐인데 이것을 보니 이해가 갑니다.

https://gist.github.com/marcelog/7b0224b63c90802996ab2dee7d7082e4

 

SQS Policy to allow an S3 bucket to publish messages

SQS Policy to allow an S3 bucket to publish messages - aws-sqs.policy

gist.github.com

이 설정은 SQS에서 QUEUE를 선택하고 

아래 화면에서 볼 수 있었습니다.

여기에 위의 gist에 있는 내용에서 나와 관련된 내용을 추가하고

S3에서 접근할테니 관련 bucket 정보를 추가하면 됩니다.

 

Bucket이 1개만 추가되지 않을 수도 있는데 2개 이상 추가도 됩니다. 

2개의 bucket을 [   ] 배열로 묶으면 더 보기 좋을텐데 방법을 못 찾았습니다.

Principals는 Everybody(*)로 두었는데, 

account로 제한을 더 두는게 나을 것 같은데 방법을 못 찾겠다. 제한을 좀 더 두고 싶은데..

  • arn:aws:iam::계정의ID:root 로만 되는것 같고 *을 줄 수가 없다. 내가 못 찾은걸지도 모르겠지만... 

 

S3에서 event 생성 잘 됩니다.

 

+ Recent posts