S3 ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ Mail.ru ํด๋ผ์šฐ๋“œ ์†”๋ฃจ์…˜์˜ ์›นํ›„ํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ˆ

S3 ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ Mail.ru ํด๋ผ์šฐ๋“œ ์†”๋ฃจ์…˜์˜ ์›นํ›„ํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ˆ
๋ฃจ๋ธŒ ๊ณจ๋“œ๋ฒ„๊ทธ ์ปคํ”ผ ๋จธ์‹ 

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜๋Š” ํ•„์š”ํ•œ ์ˆœ๊ฐ„์—๋งŒ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฆฌ์†Œ์Šค์˜ ๋น„์šฉ ํšจ์œจ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์ถ”๊ฐ€ ํด๋ผ์šฐ๋“œ ์—”ํ„ฐํ‹ฐ๋ฅผ ์ž‘์—…์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ FaaS๊ฐ€ ์•„๋‹Œ ์›นํ›…์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ ์›นํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํŠœํ† ๋ฆฌ์–ผ ์˜ˆ์ œ๋ฅผ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ ๋ฐ ์›นํ›„ํฌ์— ๋Œ€ํ•œ ๋ช‡ ๋งˆ๋””์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด HTTP/HTTPS๋ฅผ ํ†ตํ•ด S3 ๋˜๋Š” ๋‹ค๋ฅธ API(๊ตฌํ˜„์— ๋”ฐ๋ผ ๋‹ค๋ฆ„)๋ฅผ ํ†ตํ•ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ํด๋ผ์šฐ๋“œ์— ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›นํ›„ํฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ์ž ์ •์˜ HTTP ์ฝœ๋ฐฑ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ฝ”๋“œ๊ฐ€ ์ €์žฅ์†Œ๋กœ ํ‘ธ์‹œ๋˜๊ฑฐ๋‚˜ ๋ธ”๋กœ๊ทธ์— ๋Œ“๊ธ€์ด ๊ฒŒ์‹œ๋˜๋Š” ๋“ฑ์˜ ์ด๋ฒคํŠธ์— ์˜ํ•ด ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์›๋ณธ ์‚ฌ์ดํŠธ๋Š” Webhook์— ์ง€์ •๋œ URL๋กœ HTTP ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ•œ ์‚ฌ์ดํŠธ์˜ ์ด๋ฒคํŠธ๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์˜ ์ž‘์—…์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์œ„ํ‚ค). ์†Œ์Šค ์‚ฌ์ดํŠธ๊ฐ€ ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์ธ ๊ฒฝ์šฐ ์ด๋ฒคํŠธ๋Š” ํ•ด๋‹น ์ฝ˜ํ…์ธ ์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์œผ๋กœ ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ž๋™ํ™”๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ„๋‹จํ•œ ์‚ฌ๋ก€์˜ ์˜ˆ:

  1. ๋‹ค๋ฅธ ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€์— ์žˆ๋Š” ๋ชจ๋“  ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์ด ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ฆ‰์‹œ ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ผ์˜ ์ผ๋ จ์˜ ์ถ•์†ŒํŒ ์ž๋™ ์ƒ์„ฑ, ์‚ฌ์ง„์— ์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€ ๋ฐ ๊ธฐํƒ€ ์ด๋ฏธ์ง€ ์ˆ˜์ •.
  3. ์ƒˆ ๋ฌธ์„œ ๋„์ฐฉ์— ๋Œ€ํ•œ ์•Œ๋ฆผ(์˜ˆ: ๋ถ„์‚ฐ ํšŒ๊ณ„ ์„œ๋น„์Šค๊ฐ€ ๋ณด๊ณ ์„œ๋ฅผ ํด๋ผ์šฐ๋“œ์— ์—…๋กœ๋“œํ•˜๊ณ  ์žฌ๋ฌด ๋ชจ๋‹ˆํ„ฐ๋ง์—์„œ ์ƒˆ ๋ณด๊ณ ์„œ์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›์•„ ํ™•์ธํ•˜๊ณ  ๋ถ„์„ํ•จ)
  4. ์•ฝ๊ฐ„ ๋” ๋ณต์žกํ•œ ๊ฒฝ์šฐ์—๋Š” ํ•„์š”ํ•œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํฌํ•จ๋œ ํฌ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ž‘์—… ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉฐ ์ฒ˜๋ฆฌ ํ›„ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ถ•์†Œํ•˜๋Š” Kubernetes์— ๋Œ€ํ•œ ์š”์ฒญ ์ƒ์„ฑ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, MCS(Mail.ru Cloud Solutions) ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ ๋ฒ„ํ‚ท์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์›นํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ AWS ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์—์„œ ๋™๊ธฐํ™”๋˜๋Š” ๊ฒฝ์šฐ ์ž‘์—… 1์˜ ๋ณ€ํ˜•์„ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ๋กœ๋“œ๋œ ๊ฒฝ์šฐ์—๋Š” ํ์— ์›นํ›„ํฌ๋ฅผ ๋“ฑ๋กํ•˜์—ฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ œ๊ณตํ•ด์•ผ ํ•˜์ง€๋งŒ ํ›ˆ๋ จ ์ž‘์—…์˜ ๊ฒฝ์šฐ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ  ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์—…๋ฌด ๊ณ„ํš

์ƒํ˜ธ์ž‘์šฉ ํ”„๋กœํ† ์ฝœ์€ ๋‹ค์Œ์— ์ž์„ธํžˆ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. MCS์˜ S3 ์›นํ›… ๊ฐ€์ด๋“œ. ์ž‘์—… ๊ณ„ํš์—๋Š” ๋‹ค์Œ ์š”์†Œ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • ์ถœํŒ ์„œ๋น„์Šค๋Š” S3 ์Šคํ† ๋ฆฌ์ง€ ์ธก์— ์žˆ์œผ๋ฉฐ webnhook์ด ํŠธ๋ฆฌ๊ฑฐ๋  ๋•Œ HTTP ์š”์ฒญ์„ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„, HTTP ๊ฒŒ์‹œ ์„œ๋น„์Šค์˜ ์š”์ฒญ์„ ์ˆ˜์‹ ํ•˜๊ณ  ์ ์ ˆํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์–ด๋–ค ์–ธ์–ด๋กœ๋“  ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์—์„œ๋Š” Go๋กœ ์„œ๋ฒ„๋ฅผ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

S3 API์—์„œ ์›นํ›… ๊ตฌํ˜„์˜ ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์€ ๊ฒŒ์‹œ ์„œ๋น„์Šค์— ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋Š” ๊ฒŒ์‹œ ์„œ๋น„์Šค์˜ ๋ฉ”์‹œ์ง€ ๊ตฌ๋…์„ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(๋‹ค๋ฅธ ์›นํ›… ๊ตฌํ˜„์—์„œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌ๋… ํ™•์ธ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Œ).

๋”ฐ๋ผ์„œ ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์ž‘์—…์„ ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฒŒ์‹œ ์„œ๋น„์Šค์˜ ๋“ฑ๋ก ํ™•์ธ ์š”์ฒญ์— ์‘๋‹ตํ•˜๊ณ ,
  • ๋“ค์–ด์˜ค๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Webhook ์ˆ˜์‹  ์„œ๋ฒ„ ์„ค์น˜

Webhook ์ˆ˜์‹  ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด Linux ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์„œ์—์„œ๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด MCS์— ๋ฐฐํฌํ•˜๋Š” ๊ฐ€์ƒ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์„ค์น˜ํ•˜๊ณ  ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install git
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  bc dns-root-data dnsmasq-base ebtables landscape-common liblxc-common 
liblxc1 libuv1 lxcfs lxd lxd-client python3-attr python3-automat 
python3-click python3-constantly python3-hyperlink
  python3-incremental python3-pam python3-pyasn1-modules 
python3-service-identity python3-twisted python3-twisted-bin 
python3-zope.interface uidmap xdelta3
Use 'sudo apt autoremove' to remove them.
Suggested packages:
  git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui 
gitk gitweb git-cvs git-mediawiki git-svn
The following NEW packages will be installed:
  git
0 upgraded, 1 newly installed, 0 to remove and 46 not upgraded.
Need to get 3915 kB of archives.
After this operation, 32.3 MB of additional disk space will be used.
Get:1 http://MS1.clouds.archive.ubuntu.com/ubuntu bionic-updates/main 
amd64 git amd64 1:2.17.1-1ubuntu0.7 [3915 kB]
Fetched 3915 kB in 1s (5639 kB/s)
Selecting previously unselected package git.
(Reading database ... 53932 files and directories currently installed.)
Preparing to unpack .../git_1%3a2.17.1-1ubuntu0.7_amd64.deb ...
Unpacking git (1:2.17.1-1ubuntu0.7) ...
Setting up git (1:2.17.1-1ubuntu0.7) ...

์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋กœ ํด๋”๋ฅผ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~$ git clone
https://github.com/RomanenkoDenys/s3-webhook.git
Cloning into 's3-webhook'...
remote: Enumerating objects: 48, done.
remote: Counting objects: 100% (48/48), done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 114 (delta 20), reused 45 (delta 18), pack-reused 66
Receiving objects: 100% (114/114), 23.77 MiB | 20.25 MiB/s, done.
Resolving deltas: 100% (49/49), done.

์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•ด๋ณด์ž:

ubuntu@ubuntu-basic-1-2-10gb:~$ cd s3-webhook/
ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80

์ถœํŒ ์„œ๋น„์Šค์— ๊ฐ€์ž…ํ•˜์„ธ์š”

API ๋˜๋Š” ์›น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํ™”๋ฅผ ์œ„ํ•ด ์›น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๋“ฑ๋กํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. ๋ฒ„ํ‚ท ์„น์…˜์œผ๋กœ ์ด๋™ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ†ต์ œ์‹ค์—์„œ.
  2. ์›นํ›…์„ ๊ตฌ์„ฑํ•  ๋ฒ„ํ‚ท์œผ๋กœ ์ด๋™ํ•˜์—ฌ ๊ธฐ์–ด๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

S3 ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ Mail.ru ํด๋ผ์šฐ๋“œ ์†”๋ฃจ์…˜์˜ ์›นํ›„ํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ˆ

Webhooks ํƒญ์œผ๋กœ ์ด๋™ํ•˜์—ฌ ์ถ”๊ฐ€๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

S3 ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ Mail.ru ํด๋ผ์šฐ๋“œ ์†”๋ฃจ์…˜์˜ ์›นํ›„ํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ˆ
๋‹ค์Œ ํ•„๋“œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”.

S3 ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ Mail.ru ํด๋ผ์šฐ๋“œ ์†”๋ฃจ์…˜์˜ ์›นํ›„ํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ˆ

ID โ€” ์›นํ›…์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ - ์ „์†กํ•  ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค. ํŒŒ์ผ ์ž‘์—…(์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ) ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ์ด๋ฒคํŠธ์˜ ์ „์†ก์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

URL - ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„ ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค.

ํ•„ํ„ฐ ์ ‘๋‘์‚ฌ/์ ‘๋ฏธ์‚ฌ๋Š” ์ด๋ฆ„์ด ํŠน์ • ๊ทœ์น™๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฐœ์ฒด์— ๋Œ€ํ•ด์„œ๋งŒ ์›นํ›…์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ํ•„ํ„ฐ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์›นํ›„ํฌ๊ฐ€ ํ™•์žฅ์ž๊ฐ€ .png์ธ ํŒŒ์ผ๋งŒ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ ค๋ฉด ํ•„ํ„ฐ ์ ‘๋ฏธ์‚ฌ "png"๋ฅผ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„ ์ ‘์†์€ 80๋ฒˆ๊ณผ 443๋ฒˆ ํฌํŠธ๋งŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค.

ํด๋ฆญํ•ด๋ณด์ž ํ›„ํฌ ์ถ”๊ฐ€ ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค:

S3 ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ Mail.ru ํด๋ผ์šฐ๋“œ ์†”๋ฃจ์…˜์˜ ์›นํ›„ํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ˆ
ํ›„ํฌ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋Š” ํ›„ํฌ ๋“ฑ๋ก ํ”„๋กœ์„ธ์Šค์˜ ์ง„ํ–‰ ์ƒํ™ฉ์„ ๋กœ๊ทธ์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80
2020/06/15 12:01:14 [POST] incoming HTTP request from 
95.163.216.92:42530
2020/06/15 12:01:14 Got timestamp: 2020-06-15T15:01:13+03:00 TopicArn: 
mcs5259999770|myfiles-ash|s3:ObjectCreated:*,s3:ObjectRemoved:* Token: 
E2itMqAMUVVZc51pUhFWSp13DoxezvRxkUh5P7LEuk1dEe9y URL: 
http://89.208.199.220/webhook
2020/06/15 12:01:14 Generate responce signature: 
3754ce36636f80dfd606c5254d64ecb2fd8d555c27962b70b4f759f32c76b66d

๋“ฑ๋ก์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” Webhook ์ˆ˜์‹  ์„œ๋ฒ„์˜ ๋™์ž‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Webhook ์ˆ˜์‹  ์„œ๋ฒ„ ์„ค๋ช…

์ด ์˜ˆ์—์„œ๋Š” ์„œ๋ฒ„๊ฐ€ Go๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ž‘๋™์˜ ๊ธฐ๋ณธ ์›๋ฆฌ๋ฅผ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

package main

// Generate hmac_sha256_hex
func HmacSha256hex(message string, secret string) string {
}

// Generate hmac_sha256
func HmacSha256(message string, secret string) string {
}

// Send subscription confirmation
func SubscriptionConfirmation(w http.ResponseWriter, req *http.Request, body []byte) {
}

// Send subscription confirmation
func GotRecords(w http.ResponseWriter, req *http.Request, body []byte) {
}

// Liveness probe
func Ping(w http.ResponseWriter, req *http.Request) {
    // log request
    log.Printf("[%s] incoming HTTP Ping request from %sn", req.Method, req.RemoteAddr)
    fmt.Fprintf(w, "Pongn")
}

//Webhook
func Webhook(w http.ResponseWriter, req *http.Request) {
}

func main() {

    // get command line args
    bindPort := flag.Int("port", 80, "number between 1-65535")
    bindAddr := flag.String("address", "", "ip address in dot format")
    flag.StringVar(&actionScript, "script", "", "external script to execute")
    flag.Parse()

    http.HandleFunc("/ping", Ping)
    http.HandleFunc("/webhook", Webhook)

log.Fatal(http.ListenAndServe(*bindAddr+":"+strconv.Itoa(*bindPort), nil))
}

์ฃผ์š” ๊ธฐ๋Šฅ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

  • Ping() - ํ™œ์„ฑ ํ”„๋กœ๋ธŒ์˜ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„์ธ URL/ping์„ ํ†ตํ•ด ์‘๋‹ตํ•˜๋Š” ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.
  • Webhook() - ๊ธฐ๋ณธ ๊ฒฝ๋กœ, URL/์›นํ›… ํ•ธ๋“ค๋Ÿฌ:
    • ๊ฒŒ์‹œ ์„œ๋น„์Šค ๋“ฑ๋ก์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค(SubscriptionConfirmation ๊ธฐ๋Šฅ์œผ๋กœ ์ด๋™).
    • ๋“ค์–ด์˜ค๋Š” ์›นํ›…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค(Gorecords ๊ธฐ๋Šฅ).
  • ํ•จ์ˆ˜ HmacSha256 ๋ฐ HmacSha256hex๋Š” ์„œ๋ช… ๊ณ„์‚ฐ์„ ์œ„ํ•œ 256์ง„์ˆ˜ ๋ฌธ์ž์—ด๋กœ ์ถœ๋ ฅ๋˜๋Š” HMAC-SHA256 ๋ฐ HMAC-SHA16 ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • main์€ ์ฃผ์š” ๊ธฐ๋Šฅ์ด๋ฉฐ ๋ช…๋ น์ค„ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  URL ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„์—์„œ ํ—ˆ์šฉํ•˜๋Š” ๋ช…๋ น์ค„ ๋งค๊ฐœ๋ณ€์ˆ˜:

  • -port๋Š” ์„œ๋ฒ„๊ฐ€ ์ˆ˜์‹ ํ•  ํฌํŠธ์ž…๋‹ˆ๋‹ค.
  • -address - ์„œ๋ฒ„๊ฐ€ ์ˆ˜์‹ ํ•  IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค.
  • -script๋Š” ๋“ค์–ด์˜ค๋Š” ๊ฐ ํ›„ํฌ์— ๋Œ€ํ•ด ํ˜ธ์ถœ๋˜๋Š” ์™ธ๋ถ€ ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.

์ผ๋ถ€ ๊ธฐ๋Šฅ์„ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

//Webhook
func Webhook(w http.ResponseWriter, req *http.Request) {

    // Read body
    body, err := ioutil.ReadAll(req.Body)
    defer req.Body.Close()
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    // log request
    log.Printf("[%s] incoming HTTP request from %sn", req.Method, req.RemoteAddr)
    // check if we got subscription confirmation request
    if strings.Contains(string(body), 
""Type":"SubscriptionConfirmation"") {
        SubscriptionConfirmation(w, req, body)
    } else {
        GotRecords(w, req, body)
    }

}

๋“ฑ๋ก ํ™•์ธ ์š”์ฒญ์ด๋‚˜ ์›นํ›…์ด ๋„์ฐฉํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜, ๋“ฑ๋ก์ด ํ™•์ธ๋˜๋ฉด Post ์š”์ฒญ์—์„œ ๋‹ค์Œ Json ๊ตฌ์กฐ๊ฐ€ ์ˆ˜์‹ ๋ฉ๋‹ˆ๋‹ค.

POST http://test.com HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation
content-type: application/json

{
    "Timestamp":"2019-12-26T19:29:12+03:00",
    "Type":"SubscriptionConfirmation",
    "Message":"You have chosen to subscribe to the topic $topic. To confirm the subscription you need to response with calculated signature",
    "TopicArn":"mcs2883541269|bucketA|s3:ObjectCreated:Put",
    "SignatureVersion":1,
    "Token":ยซRPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tAยป
}

์ด ์งˆ๋ฌธ์— ๋‹ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

content-type: application/json

{"signature":ยซea3fce4bb15c6de4fec365d36bcebbc34ccddf54616d5ca12e1972f82b6d37afยป}

์„œ๋ช…์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ„์‚ฐ๋˜๋Š” ๊ฒฝ์šฐ:

signature = hmac_sha256(url, hmac_sha256(TopicArn, 
hmac_sha256(Timestamp, Token)))

์›นํ›…์ด ๋„์ฐฉํ•˜๋ฉด Post ์š”์ฒญ์˜ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

POST <url> HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation

{ "Records":
    [
        {
            "s3": {
                "object": {
                    "eTag":"aed563ecafb4bcc5654c597a421547b2",
                    "sequencer":1577453615,
                    "key":"some-file-to-bucket",
                    "size":100
                },
            "configurationId":"1",
            "bucket": {
                "name": "bucketA",
                "ownerIdentity": {
                    "principalId":"mcs2883541269"}
                },
                "s3SchemaVersion":"1.0"
            },
            "eventVersion":"1.0",
            "requestParameters":{
                "sourceIPAddress":"185.6.245.156"
            },
            "userIdentity": {
                "principalId":"2407013e-cbc1-415f-9102-16fb9bd6946b"
            },
            "eventName":"s3:ObjectCreated:Put",
            "awsRegion":"ru-msk",
            "eventSource":"aws:s3",
            "responseElements": {
                "x-amz-request-id":"VGJR5rtJ"
            }
        }
    ]
}

๋”ฐ๋ผ์„œ ์š”์ฒญ์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ญ๋ชฉ์„ ์ง€ํ‘œ๋กœ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. "Type":"SubscriptionConfirmation", ๊ตฌ๋… ํ™•์ธ ์š”์ฒญ์—๋Š” ์กด์žฌํ•˜๊ณ  ์›นํ›…์—๋Š” ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. POST ์š”์ฒญ์— ์ด ํ•ญ๋ชฉ์ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ํ”„๋กœ๊ทธ๋žจ์˜ ์ถ”๊ฐ€ ์‹คํ–‰์€ ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. SubscriptionConfirmation, ๋˜๋Š” ํ•จ์ˆ˜๋กœ GotRecords.

SubscriptionConfirmation ๊ธฐ๋Šฅ์€ ์ž์„ธํžˆ ๊ณ ๋ คํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋‹ค์Œ์— ๋ช…์‹œ๋œ ์›์น™์— ๋”ฐ๋ผ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜. ์ด ํ•จ์ˆ˜์˜ ์†Œ์Šค ์ฝ”๋“œ๋Š” ๋‹ค์Œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ Git ์ €์žฅ์†Œ.

GotRecords ํ•จ์ˆ˜๋Š” ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  ๊ฐ Record ๊ฐ์ฒด์— ๋Œ€ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ(์ด๋ฆ„์ด -script ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋จ)๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒ„ํ‚ท ์ด๋ฆ„
  • ๊ฐ์ฒด ํ‚ค
  • ๋™์ž‘:
    • ๋ณต์‚ฌ - ์›๋ž˜ ์š”์ฒญ์— ์žˆ๋Š” ๊ฒฝ์šฐ EventName = ObjectCreated | PutObject | PutObject๋ณต์‚ฌ
    • ์‚ญ์ œ - ์›๋ž˜ ์š”์ฒญ์— ์žˆ๋Š” ๊ฒฝ์šฐ EventName = ObjectRemoved | ๊ฐ์ฒด ์‚ญ์ œ

๋”ฐ๋ผ์„œ ์„ค๋ช…๋œ ๋Œ€๋กœ Post ์š”์ฒญ๊ณผ ํ•จ๊ป˜ ํ›„ํฌ๊ฐ€ ๋„์ฐฉํ•˜๋ฉด ์ด์ƒ, -script=script.sh ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

script.sh  bucketA some-file-to-bucket copy

์ด ์›นํ›… ์ˆ˜์‹  ์„œ๋ฒ„๋Š” ์™„์ „ํ•œ ํ”„๋กœ๋•์…˜ ์†”๋ฃจ์…˜์ด ์•„๋‹ˆ๋ผ ๊ฐ€๋Šฅํ•œ ๊ตฌํ˜„์˜ ๋‹จ์ˆœํ™”๋œ ์˜ˆ๋ผ๋Š” ์ ์„ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ž‘ํ’ˆ์˜ ์˜ˆ

MCS์˜ ๊ธฐ๋ณธ ๋ฒ„ํ‚ท์— ์žˆ๋Š” ํŒŒ์ผ์„ AWS์˜ ๋ฐฑ์—… ๋ฒ„ํ‚ท์— ๋™๊ธฐํ™”ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋ฒ„ํ‚ท์€ myfiles-ash๋ผ๊ณ  ํ•˜๊ณ , ๋ฐฑ์—… ๋ฒ„ํ‚ท์€ myfiles-backup์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค(AWS์˜ ๋ฒ„ํ‚ท ๊ตฌ์„ฑ์€ ์ด ๋ฌธ์„œ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค). ๋”ฐ๋ผ์„œ ํŒŒ์ผ์ด ๊ธฐ๋ณธ ๋ฒ„ํ‚ท์— ์žˆ์œผ๋ฉด ํ•ด๋‹น ๋ณต์‚ฌ๋ณธ์ด ๋ฐฑ์—… ๋ฒ„ํ‚ท์— ๋‚˜ํƒ€๋‚˜์•ผ ํ•˜๊ณ , ๊ธฐ๋ณธ ๋ฒ„ํ‚ท์—์„œ ์‚ญ์ œ๋˜๋ฉด ๋ฐฑ์—… ๋ฒ„ํ‚ท์—์„œ๋„ ์‚ญ์ œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

MCS ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€ ๋ฐ AWS ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€์™€ ๋ชจ๋‘ ํ˜ธํ™˜๋˜๋Š” awscli ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํ‚ท ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install awscli
Reading package lists... Done
Building dependency tree
Reading state information... Done
After this operation, 34.4 MB of additional disk space will be used.
Unpacking awscli (1.14.44-1ubuntu1) ...
Setting up awscli (1.14.44-1ubuntu1) ...

S3 MCS API์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ๊ตฌ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile mcs
AWS Access Key ID [None]: hdywEPtuuJTExxxxxxxxxxxxxx
AWS Secret Access Key [None]: hDz3SgxKwXoxxxxxxxxxxxxxxxxxx
Default region name [None]:
Default output format [None]:

AWS S3 API์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ๊ตฌ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile aws
AWS Access Key ID [None]: AKIAJXXXXXXXXXXXX
AWS Secret Access Key [None]: dfuerphOLQwu0CreP5Z8l5fuXXXXXXXXXXXXXXXX
Default region name [None]:
Default output format [None]:

์•ก์„ธ์Šค๋ฅผ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

AWS๋กœ:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile aws
2020-07-06 08:44:11 myfiles-backup

MCS์˜ ๊ฒฝ์šฐ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ โ€”endpoint-url:์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile mcs --endpoint-url 
https://hb.bizmrg.com
2020-02-04 06:38:05 databasebackups-0cdaaa6402d4424e9676c75a720afa85
2020-05-27 10:08:33 myfiles-ash

์•ก์„ธ์Šคํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ๋“ค์–ด์˜ค๋Š” ํ›„ํฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„์€ s3_backup_mcs_aws.sh์ž…๋‹ˆ๋‹ค.

#!/bin/bash
# Require aws cli
# if file added โ€” copy it to backup bucket
# if file removed โ€” remove it from backup bucket
# Variables
ENDPOINT_MCS="https://hb.bizmrg.com"
AWSCLI_MCS=`which aws`" --endpoint-url ${ENDPOINT_MCS} --profile mcs s3"
AWSCLI_AWS=`which aws`" --profile aws s3"
BACKUP_BUCKET="myfiles-backup"

SOURCE_BUCKET=""
SOURCE_FILE=""
ACTION=""

SOURCE="s3://${SOURCE_BUCKET}/${SOURCE_FILE}"
TARGET="s3://${BACKUP_BUCKET}/${SOURCE_FILE}"
TEMP="/tmp/${SOURCE_BUCKET}/${SOURCE_FILE}"

case ${ACTION} in
    "copy")
    ${AWSCLI_MCS} cp "${SOURCE}" "${TEMP}"
    ${AWSCLI_AWS} cp "${TEMP}" "${TARGET}"
    rm ${TEMP}
    ;;

    "delete")
    ${AWSCLI_AWS} rm ${TARGET}
    ;;

    *)
    echo "Usage: 
#!/bin/bash
# Require aws cli
# if file added โ€” copy it to backup bucket
# if file removed โ€” remove it from backup bucket
# Variables
ENDPOINT_MCS="https://hb.bizmrg.com"
AWSCLI_MCS=`which aws`" --endpoint-url ${ENDPOINT_MCS} --profile mcs s3"
AWSCLI_AWS=`which aws`" --profile aws s3"
BACKUP_BUCKET="myfiles-backup"
SOURCE_BUCKET="${1}"
SOURCE_FILE="${2}"
ACTION="${3}"
SOURCE="s3://${SOURCE_BUCKET}/${SOURCE_FILE}"
TARGET="s3://${BACKUP_BUCKET}/${SOURCE_FILE}"
TEMP="/tmp/${SOURCE_BUCKET}/${SOURCE_FILE}"
case ${ACTION} in
"copy")
${AWSCLI_MCS} cp "${SOURCE}" "${TEMP}"
${AWSCLI_AWS} cp "${TEMP}" "${TARGET}"
rm ${TEMP}
;;
"delete")
${AWSCLI_AWS} rm ${TARGET}
;;
*)
echo "Usage: ${0} sourcebucket sourcefile copy/delete"
exit 1
;;
esac
sourcebucket sourcefile copy/delete" exit 1 ;; esac

์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•ด๋ณด์ž:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80 -
script scripts/s3_backup_mcs_aws.sh

๊ทธ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ด…์‹œ๋‹ค. ์„ ํ†ตํ•ด MCS ์›น ์ธํ„ฐํŽ˜์ด์Šค test.txt ํŒŒ์ผ์„ myfiles-ash ๋ฒ„ํ‚ท์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ฝ˜์†” ๋กœ๊ทธ๋Š” ์›นํ›… ์„œ๋ฒ„์— ๋Œ€ํ•œ ์š”์ฒญ์ด ์ด๋ฃจ์–ด์กŒ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

2020/07/06 09:43:08 [POST] incoming HTTP request from 
95.163.216.92:56612
download: s3://myfiles-ash/test.txt to ../../../tmp/myfiles-ash/test.txt
upload: ../../../tmp/myfiles-ash/test.txt to 
s3://myfiles-backup/test.txt

AWS์—์„œ myfiles-backup ๋ฒ„ํ‚ท์˜ ๋‚ด์šฉ์„ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls 
myfiles-backup
2020-07-06 09:43:10       1104 test.txt

์ด์ œ ์›น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด myfiles-ash ๋ฒ„ํ‚ท์—์„œ ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์„œ๋ฒ„ ๋กœ๊ทธ:

2020/07/06 09:44:46 [POST] incoming HTTP request from 
95.163.216.92:58224
delete: s3://myfiles-backup/test.txt

๋ฒ„ํ‚ท ๋‚ด์šฉ:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls 
myfiles-backup
ubuntu@ubuntu-basic-1-2-10gb:~$

ํŒŒ์ผ์ด ์‚ญ์ œ๋˜๊ณ  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก  ๋ฐ ToDo

์ด ๊ธ€์— ์‚ฌ์šฉ๋œ ๋ชจ๋“  ์ฝ”๋“œ๋Š” ๋‚ด ์ €์žฅ์†Œ์—. ์›นํ›„ํฌ ๋“ฑ๋ก์„ ์œ„ํ•œ ์Šคํฌ๋ฆฝํŠธ์˜ ์˜ˆ์™€ ์„œ๋ช… ๊ณ„์‚ฐ์˜ ์˜ˆ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ฝ”๋“œ๋Š” ํ™œ๋™์—์„œ S3 ์›นํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ์˜ˆ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ์ฒ˜์Œ์— ๋งํ–ˆ๋“ฏ์ด ์ด๋Ÿฌํ•œ ์„œ๋ฒ„๋ฅผ ํ”„๋กœ๋•์…˜์—์„œ ์‚ฌ์šฉํ•  ๊ณ„ํš์ด๋ผ๋ฉด ์ ์–ด๋„ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์œ„ํ•ด ์„œ๋ฒ„๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋“ค์–ด์˜ค๋Š” ์›นํ›„ํฌ๋ฅผ ๋Œ€๊ธฐ์—ด(RabbitMQ ๋˜๋Š” NATS)์— ๋“ฑ๋กํ•˜๊ณ  ๊ฑฐ๊ธฐ์„œ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์›นํ›…์ด ๋Œ€๋Ÿ‰์œผ๋กœ ๋„์ฐฉํ•  ๋•Œ ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋Š” ๋ฐ ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ถ€์กฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๊ธฐ์—ด์ด ์žˆ์œผ๋ฉด ์„œ๋ฒ„์™€ ์ž‘์—…์ž๋ฅผ ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ๋ฐ˜๋ณต ์ž‘์—…์œผ๋กœ ์ธํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋กœ๊น…์„ ๋ณด๋‹ค ์ƒ์„ธํ•˜๊ณ  ํ‘œ์ค€ํ™”๋œ ๋กœ๊น…์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

ํ–‰์šด์„ ๋น•๋‹ˆ๋‹ค!

์ฃผ์ œ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ž๋ฃŒ:

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€