-
Notifications
You must be signed in to change notification settings - Fork 10
/
0423.txt
287 lines (287 loc) · 31.1 KB
/
0423.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
예, 안녕하세요. 포프입니다.
제가 요즘 CTO쪽 일을 많이하고 있잖아요.
근데 CTO쪽 일을 많이 하다 보면은.. 가장 이제..
신경을 써야 되는 부분들이 그런 부분들이더라구요.
제가 워낙 좋아하는 부분이기도 한데,
어떤 프로세스를 잡고, 아니면 어떤 코딩 규약을 만들고, 내부적으로
아니면, 내부에서 어떤 컬쳐(Culture)를 가지고 있어야
실수를 덜 할까?
그게 가장 큰 문제.
물론, 실수를 간단히 하고, 빨리 고칠 수 있는 부분들
이런 부분들은 별 문제가 없어요.
근데, 이 실수가 쉽고. 실수가 날 경우, 이거를 찾아서 고치기가 드럽게 어려운 경우
그런 경우들은 이제 최대한 막으려고 하죠.
그러면은 이제 당연히 실수를 막기 위해서는
프로세스를 잘 잡아야 하는 부분이 꽤 많아요
프로세스만 잘 잡는것만으로, 실수를 90프로 100프로 이렇게 줄일수도 있어요. 사실은.
근데 또 하나의 문제는, 프로세스가 복잡하면 복잡해질수록
원래부터 실수를 안하던 사람들은
이제 짜증이 나는거죠. 효율이 안나오니까. 쓸데없는 프로세스 왜 밟지? 나는 실수를 안하는데..
이게 그 중간사이의 밸런스가 굉장히 중요해요
근데 프로세스와 실수를 덜하는것과, 복잡한거가 언제나 반드시 반비례관계는 아니에요.
프로세스를 잘 잡는 것만으로도
실수를 굉장히 줄이지만
그렇게 사용하지도 복잡하지 않은 그런 프로세스가 나올 수가 있거든요
결과적으로는, 좋은 CTO라던가 좋은 아키텍트, 그런 사람들을 구분짓는거는 그런 부분인거 같아요.
뭐, 그럴라면은 당연히 사람을 잘 이해하는것도 중요하겠죠.
왜냐하면은 "아 내 직원이 이런 애들인데, 당연히 여기서 실수를 하겠구나"
아니면, 여기서 몇 번의 실수를 해왔구나.
"아, 그럼 저거는 당연히 저 직원의 문제기도 하지만, 어차피 그런 직원을 가지고 있는 이상 어떻게 이걸 고쳐나갈거냐"
그러면 어떤 프로세스를 만들거냐
이 프로세스를 개발을 잘 하는 사람들이. 아마 훨씬 훌륭한 아키텍트고 CTO라고 생각을 해요
제가 그런 일들을 많이 해요
그러다가 최근에 제가 이제 또 굉장히
몇년 동안 짜증나하고 있다가, 드디어
정립을 시킨 시스템이 있어요
그게, 기획이 나왔고. 저희쪽에서 구현이 들어가지만
구현 들어가다가 몇개 잘못된게 나오면 고칠게 있겠죠?(웃음)
어쨌든간에 뭐냐? 뭐냐하면, 세팅이에요 세팅.
제가 말하는 세팅이 뭐냐하면, 웹 서버 나갈때의 세팅을 말하는 거에요
웹서버를 보통 하는걸 보면은
테스트를 거쳐야되니까, 환경을 여러개를 나눠요
하나가 이제.. 스테이징, 테스트 서버, 그다음이 개발서버, 개발은 내 로컬 개발
테스트는 서버에 올려서 테스트하는거
그 다음이 스테이징 서버. 프로덕션 나가기 전에 정말 라이브 환경하고 비슷한 환경에서, 거의 비슷한 환경에서 테스트하고.
마지막에 프로덕션 나가죠.
그럼 환경에 4개에요
그러면, 제가 서버를 넣을 때, 환경이 4개라는 거는 DB도 네개라는 얘기에요.
이게 라이브에 있는 데이터를 테스트 서버에서 직접 연결을 하거나, 그러는 경우가 생기면은..
결과적으로 개발자한테 모든 라이브데이터를 공개를 하겠다는 거거든요
그러면 그 안에 있는 온갖 유저정보라던가 이런것도 솔직히 공개가 되는거에요
그러면 그 순간에
프라이버시 브릿지(Privacy Bridge)가 일어날 일이 굉장히 많겠죠?
사실 한국에서 예전에 농협이었나? 거기가 털린 것도 개발자인지 사무직인지..
그 사람 컴퓨터에 유저정보가 다 들어있던걸로 알고 있어요.
DB에서 나온거를 갖고 있다가 털린거다.
그래서 결과적으로는 그렇게 데이터가 유출 될 경로를 줄여야만, 이제 데이터 털릴 일도 적은거에요.
그래서 그런게 있고.
또 다른 셑.. DB가 4개로 갈린다면은
저희 웹서버가 있고, DB가 네 개 갈려야되잖아요? 환경따라.
그러면 어느 환경에 내 서버 실행 파일을 올리냐에 따라 그거에 따른 DB 커넥션 스트링(Connection string), 그걸 바꿔줘야되요.
물론 이걸 코드에 박아갖고 하시는 분들도 있지만
(한숨) 그런 중요한 데이터가, 그런 중요한 비밀 키들이
소스 컨트롤에 들어간다는것 자체가 이미 시큐리티 브린지(Security bridge)에요. 제 개념에서는.
그래서 그거는 노 노고.
그거를 빼서 어떻게 환경을 잡을 필요, 방법이 필요한거죠.
뭐, 그 외에도 다양한 것들이 있어요. 설정이라는거는.
내가 마이크로 서비스를 한다. 그러면 당연히 테스트 서버에서는 다른 테스트 서버를 히트(Hit)해야 되잖아요?
그럼 그 서버 URL 그것도 세팅으로 들어가야 되고, 그건 당연히 환경따라 달라지죠?
그 외에 DB에 쓰는, Encryption 키라던가 이런것도 당연히 환경마다 달라져야되요
그러면, 그런 환경을 쫙 만들어야 되거든요
그럼 여태까지 보통 이런걸 환경 관리를 어떻게 해 왔냐?
제일 첫번째(방법). 절대 하지 말야될 짓
(헛웃음)이게 소스컨트롤에 들어간 소스에 환경 박아놓는거
제가.. 대기업에서, 한국 대기업이요. SI로 일하는 사람들의 코드를 최근에 본 적이 있어요.
보는데.. 소스코드에 DB 커넥션 키가 들어가있고 그거를.. 그냥 깃에 넣어놨더라구.
문제는.. 깃이 우리꺼니까 상관없지 않느냐고 우길수는 있는데..
소프트웨어가 발전하다보면은 어느순간 소스 리포(repo)를 열어서 외주를 맡길경우도 있고, 여러가지 일이 벌어져요.
근데 소스컨트롤이라는건 모든 히스토리가 담겨있는 거잖아요?
그러면 그.. 우리가 외주하는 사람들한테 프론트엔드(Front-end) 기능만 주고 싶었는데
어쨌든 소스는 공유해야 되니까.. 당연히 나중에 사람이 "아 문제 없겠지"하면서 공유를 했어.
근데 뒤지다 보니까, 거기에 서버키가 나오는거야 서버 DB키 같은거
그럼 DB는 털리는거죠
그래서 절대 그런 정보는 들어가면 안돼요.
그리고 내 서버가 어디에 있느냐, 그 URL로도 내부에 있는 서버는.. 그런것도 공개가 되면 안돼요.
당연히 내 로컬에서 어차피 도는거, 로컬호스트 포트 몇으로 도는건 상관이 없죠.
어차피, 니가 내 로컬호스트 접속할 수는 없으니까
그래서 그렇게 하시는 분들이 있지만, 그건 노노에요.
그리고 두번째는, 제가 한동안 많이 쓰던 방법이고, 사실 지금까지도 이렇게 썼던 방법인데
AWS라던가 Azure쪽에서 이제.. 자동으로 스케일해주는 앱 서비스 들이 있잖아요.
앱서비스가 아마 Azure꺼고, AWS가 beansTalk라고 하던가? 그런게 있어요.
그러면은 거기에 보면은 이제 설정을 환경변수처럼 해 줄 수가 있어요.
그러니까 웹 대쉬보드(Dash board)들어가서 키-밸류, 키-밸류, 키-밸류 넣으면은 그것만으로 그거를 웹 서버에서 읽을 수가 있어요. 환경변수로 저장이 됐으니까
물론 그거를 쉽게 읽게하기 위해서 ASP.NET Core 같은 경우에는 그냥 Add Environment variable하면은 거기서 읽어오게 하는 방법이 있죠.
그래서 그걸로 되게 많이 썼고, 그걸로 쓴 이유가 뭐냐하면.
어차피 제가 테스트 환경, 스테이징 환경, 라이브 환경은 Slot이 여러개로.. 서버가 어차피 따로 있는 거거든요.
그러면 그 서버 인스턴스(instance) 들어가서, Azure같은데서 앱 포탈(Web portal)들어가서 거기 Application Setting이라고 있어요.
그럼 거기에서, "아 키는 다 똑같애" DB 커넥션 스트링, 저쪽도 DB 커넥션 스트링. 그러나 밸류(Value)만 바꿔주면 되죠.
이렇게 하는 방법으로도 충분히, 환경에 따른 모든 변수를 설정이 가능을 했어요.
그리고, 이미 Azure Web Service에서 각 슬롯(Slot)마다 접근 권한을 설정을 해줄 수가 있어요.
그러니까.. "너 개발자는 Prod 권한 있는애, Prod 볼 수 있어"
"얘는 테스트만 권한 있는 애" 그러면 Prod는 App Setting 못 보고 테스트 Slot은 니 맘대로 바꿔.
이렇게 해줄 수 있는거였어요. 그러면 그것만으로 아까 말했던 중요한 정보가 빠져나가는 그런 단점은 다 고칠 수가 있고.
이런 커넥션 스트링이나 이런것들이 소스 코드에도 안들어가니까 문제가 없죠.
그래서 그게 두 번째 방법이고 저희가 많이 써왔던 거고..
세 번째 방법은, 이런 클라우드가 흥하기 전에 많이 썼던 방법이긴 한데.
아주 안전한 방법은 아니에요.
닷넷 옛날꺼.. ASP.NET 보면은 Web Transform이라는게 있었어요.
뭐냐하면.. Web Config라는거에 모든 Config이 들어가 있고, 환경따라.
얘 Staging이면은 Staging은 요 밸류를. 그러니까 Web Config이라는게 Xml 파일이에요
그러면 키하고 밸류가 비슷하게 있는거거든요? 그러면 거기다가
"아, 스테이징 간다고?" 그러면 요거를.. 요 값을 새로운 값으로 바꿔 키 따라 매치해서. 그걸 바꿔갖고..
새로 웹 컨피그 파일을 뽑아줘요. 내가 스테이징용으로 퍼블리쉬(publish)할 때 prod용으로 퍼블리쉬할 때.
그러나 역시 이거의 문제는 뭐였냐면은 Config파일 자체가 소스 코드에 같이 들어가니까
그러면 그거에 따라서 여전히 소스코드에 들어가는 문제가 있었고, 그렇기때문에 프로덕션 갈때는 사람이 손수 바꾸거나 이런 일이 있었어요.
네 번째 방식. 어찌보면은 지금 말했던 세번째 방식?에 단점을 고친거였는데.
테스트서버나 이런거는.. 내부서버인 경우에, 그냥 다 아까 말했던 Web Config이라던가 이런걸로 다 해갖고 tranform하고.
Prod 갈 때는, 누군가가 손으로 딱 잡아갖고, Prod는 요 키가 요 밸류야. 요 키가 요 밸류야 하고 파일을 저장해 놓은 다음에
Prod 나갈 때, 빌드를 Prod용으로 따로 돌려요.
그러면서 이 파일을 대신 써 갖고, 같이 디플로이(Deploy)해.
그래서 이런식으로 했던거에요. 예전에 했던 수동작업이었죠.
그래서 이렇게 네 가지 방식이 있었어요.
하나는, 다시 정리를 할게요. 소스코드에 집어 넣는 법.
두번째는, 환경변수에 쓰는 법.
세번째는, Web Config 이용하는 법. 역시 Transformation이용하고, 역시 소스컨트롤들어가는게 똑같아요.
네 번째는, 미리 파일 만들어두고. 그 파일을 이제 권한 있는 사람만 가지고 있는거죠.
그리고, 그 Prod에 갈 때 그걸 손수 집어갖고 넣는법. 이렇게 있었어요.
아 한가지 더 있다. 다섯가지 방법 얘기할게요.
다섯번째, 데이터베이스 이용하는 법
세팅이 결국 키하고 밸류 짝이잖아요? 페어(Pair)
그러면은 그 키하고 밸류를 데이터베이스에 박아놔요
그리고 서버가 올라갈 때 그 데이터베이스 연결을 해갖고 그 값을 읽어오는거에요
그러면 이제 DB 테이블이 여러개가 있겠죠? 하나는 테스트용 하나는 prod용 하나는 Staging...
이거는 솔직히 굉장히 괜찮은 방법이었고, 전에 회사에서 많이 썼던 방법이기도 해요.
근데 단점이 뭐였냐하면은, DB 세팅이.. DB커넥션을 만들어야 되는데
이거를 이제 따로 분리를 해 놓는 경우가 흔하다고는 하지 않고, 좀 안전하죠.
왜냐하면 이미 애플리케이션이 도는 DB와 세팅이 도는 DB가 그.. 테이블이요.
한 DB에 들어가 있으면, 뭐 테이블마다 권한을 조정할 수도 있지만 당연히
이게 권한을 잘못줘버리면, 너는 애플리케이션 데이터만 보여주고 싶었는데 어쩌다가 잘못된 개발자가
모든 세팅을 보는거에요. Encryption key부터 이런거를.. 그것도 좀 말이 안돼잖아요
그러니까 DB는 약간 액세스 컨트롤(Access control)이... 할려면 할 수 있는데 생각보다 실수를 많이 할 수 있어서
잘못 실수로 정보가 공개될 수 있는 단점들이 있어서 조금 애매한 부분이었어요.
어쨌든 이 다섯가지.. 그랬죠.
저희도 뭐.. 아까 말했던 DB도 썼었고 옛날에, 웹 트랜스폼도 옛날에 회사에서 쓰긴 썼었고.
그 다음에, 웹 트랜스폼 대신에 나온게 닷넷코어에서는 json파일 읽는거에요.
json으로 그냥 만들어갖고, 환경마다 다른 json 만들어갖고 알아서 이렇게 만들잖아요? 똑같은거에요.
그래서 그것도 해봤고..
그러다가 이제 이거하고 아까 말했던 환경변수를 섞어갖고 하는것도 했어요 지금이 가장 저희가 쓰고있는 방법이 그건데
그런데 환경변수 쓰는걸 좋아요. 솔직히 액세스 컨트롤 환경에서도 가장 좋고.
왜냐하면은, 왠만한 개발자는 서버에 대한 접근권한이 없는게 정상이에요. 라이브 서버에 대해서.
왜냐하면 거기에 뭐 잘 못 깔면 난리가 나니까.. 그래서 이거는 완벽하게 새로..
프로비저닝(provisioning)이라고 하나? 뭔가 서버로 올라갈때는 새로 이미지해서 새로 서버로 올리거나
이미 앱서비스에서 해주고 있죠? 애져에서는. 그래서 그냥 클린 머신, 아무도 손 안댄 클린 머신에다가
이제 아, 설정만 집어넣어주면 되는거? 근데 이 설정을 볼 수 있는 권한은 어차피 아까 말했듯이. 애져 포탈에서 해줄 수 있고, 애져 포탈은 누가 들어왔는지 다 로그가 남고.
그리고 그 실서버에 접근할 수 있는 권한 자체가 아예 없으니까.. 안전한거에요
그 환경변수를 뽑아올 수가 없는거에요. 그쵸? 그 프로그램 짜갖고 뽑아오려면 또 디플로이 해야겠지만.. 디플로이 권한 자체가 없으면 되니까..
단점이 뭐였냐하면은,
이 서버가 커지면 커질수록 환경 변수가, 아까 말했던 잡아줘야될게 수십개가 되요.
한 4-50개가 되는 경우도 있어요.
그러면 40개 세팅이 쫙~ 있어요. 그죠?
그래 40개 세팅 잡을 수 있지, 좋아. 근데 애져의 문제인데 이거는..
40개 세팅이 있잖아요. 근데 추가한 순서대로 그냥 키가 바뀌어있어요. 이거를 무슨 이름 순으로 정렬하는 법도 없고, 그래서 가끔 뭐가 빠졌는지 보기가 되게 애매하고
두번째는, 개발자가 개발하면서 테스트서버에 모든 환경변수를 쫙 만들어놨어요.
아 좋아, 만들어놨어. 그다음에 이제 Prod로 나가야되, 나가는데.
어, 실수로 Prod에 환경변수를 설정 안해놓은거야..
그러면, 서버를 이제 올리고 난 다음에 그게 안돼는걸 알아요.
근데 안돼는걸 아는게, 그 환경변수가 없다는걸 아는게 아니라.. 뭔가 안돌아.. 그러면 그때부터 하나하나 뒤지는거야. 이게 왜 안될까.
환경변수 하나씩 다 비교해보고 50개 다 비교하는데, 아까 말했듯이 순서가 안맞어.. 되게 힘들거든요?
그래서 그런 부분이 되게 짜증이 났어요.
그러면 이걸 해결하기 위해선 제가 아까 말했던거처럼, 웹 트랜스폼, Json을 이용해서 한번에 파일 딱 올라가는게 맞지만..
아 그리고 소스컨트롤 들어가잖아, 말이 안돼는거에요.
그래서 생각을 많이했어요. 이걸 어떻게하면 좀 고칠까.
그래서 결국에는 어떤 생각을 해냈냐하면은
아 적어놓은게 있으니까, 적어놓을걸 잠깐 보면서 얘기를 할게요.
제가 하고 싶었던거는, 그냥 누군가가 이렇게 손작업을 하지 않아야 되지만.. 그죠?
그렇다고 소스컨트롤에 이게 다 들어갈 수는 없다.
그러면 어차피 어딘가 손작업이 있는데, 그렇다면은 손작업을 해갖고, 키를 빼먹었거나 이런거 자체를 빌드 동안에 찾아내서 아예 디플로이를 금지시키자는 생각을 했어요.
그래서 생각을 했던게, 세팅 매니저라는걸 만들자.
개념이 어떻냐하면은, 일단, 시작은 실섭이든.. 그.. 아니 단계별로 얘기해야겠다.
첫번째는, 아까 말했던 웹 트랜스폼같은 파일, 그 닷넷코어라면 appsetting.json파일 거기서 시작을 하자
여기에, 넣을 수 있는 값은 다 넣자
일단은 모든 키를 정리하자 그랬어요. 실제 서버에서 쓰는 모든 세팅키들을 일단 집어넣고
값을 넣을때는 공개되도 문제없는 값들 있잖아요? Timeout 시간이 몇초라던가 이런거는 공개하자.
하지만, 만약에 무슨 Encryption key라던가 DB Connection 이런거는 그냥 '빈칸'으로 만들자
그 애플리케이션, 아니 apsettings.json 닷넷코어에서.
그러면 이거는 가장 기본이 Default가 되는 값이고, 그러면 이거는 어떤 환경에 쓰이는 걸로 했어요.
그러면 이제 그 다음에는, 모든 환경따라 json이 바뀌거나 이런거잖아요?
근데 굉장히 거기에 넣을 수 있는 값들이 생각보다 없어요. 공개되면 안돼는 값들이 많기 때문에..
그리고 이제 로컬에서 개발을 할 때는
닷넷코어 쪽에 보면은, 유저 시크릿 매니저라는게 있어요. 이게 뭐냐?
예전에는 내가 로컬에서 테스트할때는 아까 말했던 json파일을 손수 고쳐갖고 막 테스트하고 집어넣기 전에 리버트(Revert)하면 된다고 생각 했어요.
근데 사람들이 이걸 실수로 집어넣는 경우가 또 있어. 그럼 그 순간 이미 노출이 된거거든요? 서버 정보는?
근데 닷넷코어에서는 유저 시크릿 매니저를 깔면은 그 세팅을 제 로컬 홈 폴터가 있잖아요?
아무도 접근 못하고 저만 접근할 수 있는 폴더. 유저가. 그 폴더에서 만들어주고 그걸 읽어와요
그래서 내가 로컬에서 오버라이드해서 써야되는건 거기 넣으면 되는데 문제는..
안전한데, 문제는 아까말했던 appsetting.json하고 제 시크릿 있는 세팅하고, 또 이제..
하나하나 다 값을 복사해갖고 집어넣는 불편함이 있죠
그래서 이것도 좀 자동화 시킬려고 생각을 했어요
그래서 생각을 했던게, 아 우리가 첫번째는 생각하는게 뭐냐하면 개념적으로.
세팅이라는걸 잘 생각을 해봐요. 키가 있어요 DB Connection key고 무슨 key고 Encryption key고.. 뭐 이렇게 쫙 한 줄 한 줄 있다고 봐요.
그러면, 그 다음에는 내 로컬에서는 이 값이 어떻게 되야하는가? 그건 하나의 컬럼이에요. 그죠?
그리고 테스트에서는 어떤게 되든 컬럼이죠. 스테이징? 도 컬럼이에요. 프로덕션도 컬럼이이에요.
그래서 제 개념에서는 뭐였냐하면은. 아니 이거는 솔직한 얘기로 어떤 값이 미싱(missing)되는지 알고 싶으면 단순하게,
엑셀 같은데서 2D를 이렇게 만들어갖고, 값 채워넣고 빈거만 찾으면되는거라는 개념을 했어요.
물론 저희가, 엑셀에 집어넣고 이러면 아까 말했듯이 한컬럼은 누구만 봐야되고 다른 컬럼은 누가 못보고 이런 문제가 있으니까 관리가 안 됐죠.
그래서 그냥 이거를 아 차라리 이거를 우리 내부에서 쓰는 툴서비스를 만들자
그래서 거기서 시작을 했어요. 우리가 내부에서 사람들이 로그인할 수 있는 서비스를 만들어서 내부 유저만, 개발자들이
그래서 그 값을 채워넣게하는 웹 페이지를 하나 만들자
그러면 아까 말했던 settings DB하고 되게 비슷해 지는거에요.
이 데이터가 올 수 있는 부분이 되게 많아져야 정상이에요. 사실은 그쵸?
그래서 이제 개념을 잡았어요. 어떻게 잡아야 되냐? 아까 처음에 말했던 appsetting.json파일 있죠?
거기에는 저희가 실제 쓰고 있는 모든 키가 등록이 되 있어야 되요. 그러면 빌드를 하는 도중에, 빌드를 하는 도중에
이 파일을 읽어서, 빌드 서버가. 여기 나오는 키들 다 있죠? 그리고 아까 말했던 Default 값들 있잖아요. 그럼 그걸 모아갖고 저희쪽 관리하는 서버에 쏴 주는 거에요.
그러면 그 서버는 이걸 받아갖고, 아.. 웹 서버 올릴거에는 이런이런이런 키가 들어가야되는구나 그리고 Default 값은 이거이거이거 구나 이 값은 비었구나.. 이거를 쫙 DB에 저장을 쫙 해놔요.
그리고 그 아까 빌드를 할 때, 이 키하고 실제 웹 서버에서 쓰는 옵션들하고 왜냐하면 저희는 모든 옵션을 string으로 안읽어요
저희는 클래스로 만들어서 이제 그거를 닷넷코어 보면은 옵션스 해갖고 옵션을 읽는게 있어요.
클래스만 잘 짜놓으면 그 구조따라 json에서 읽어버리죠.
그럼 저희는 이제 생각했던게 뭐냐하면, 빌드 과정 동안에, Options라고 되 있는 모든 클래스를 읽어서 거기에 있는 모든 키값들이 이 json 파일에 있는거를 확인을하자.
이게 없다면, 뭔가 하나가 누락된게 있다면 그 순간 빌드를 빠갠다.
그러면 빌드가 아예 안만들어지니까 개발자가 실수로 json파일을 안넣었거나 이런 경우는 옵션을 넣었는데 json파일을 안넣은 경우에는 빌드가 뽀개지니까 다시 고쳐야겠죠.
그거를 유닛테스트로도 가능하다고 생각을했어요 사실은. 그래서 그렇게 만들자
빌드 과정에 돌리고, 깨지고, 사용자가 고치고, 그럼 빌드가 끝나는 순간 이 json 파일은 실제 서버에 쓰는 모든 키를 가지고 있어요.
그리고 그게 저희가 말했던 다른 웹서비스 내부 관리 툴에 (손짓)해서 관리툴은 이 서버에는 이제 이런 키들이 있어야 된다는걸 알게 되죠
그럼 그 다음에는 테스트 환경이라던가 스테이징 환경 프로덕션 환경에서 누가 뭔가를 고쳐야 될 때잖아요.
비어있는 칸을 채워야 되잖아
그러면 저희 개발자가 서버에 로그인 하는 거에요. 웹페이지 내부 웹페이지에
가면은 "야 이거 세팅 보여줘"하면은 세팅이 쫙 나오는거야
테스트 서버에서 비어있는 세팅이 다 보이겠죠
그러면 개발자는 테스트 환경을 아니까 그걸 채워 넣는 거에요
그리고 그 다음에 스테이징 서버나 프로덕션 서버는 보통 굉장히 제한된 사람을 가지고 있는게 정상이거든요?
그럼 이거는 그냥 비어있고, 어떤게 없다는것 정도는 보여줄 수 있어요. 그냥. 이 엔트리(Entry)가 없어.
그러면 그거를 이제 넣을 수 있는 사람한테 불러갖고 넣어주세요라고 하면 되는 거죠
그러나 사람들은 언제나 그렇지는 않지
그럼 그 다음 단계가 재밌어져요.
그 다음 단계가 뭐였냐하면은
테스트 서버에 올라갈 때가 있잖아요. 그럼 테스트 서버에 올라갈 때 빌드 머신이나 디플로이 머신은 뭐하냐?
저희가 지금 만들었던거 있죠? 관리 툴, 관리 서버 그거를 호출해갖고 빌드 도중에 "야, 나 테스트 서버 올라가야 되니까 거기에 필요한 세팅파일 json파일 내놔"
그러면 얘가 그거를 주는 거에요. 근데 아까 말했듯이 테스트 서버에서 비어있던거 있죠. 사람이 안채워 넣었을 때.
그게 비어 있으면 에러 주는거에요. "야 나 그거 못해, 없어" 그러면 빌드 서버나 디플로이 단계가 딱 빠개지는거에요.
이 파일을 못받아 왔잖아. 빌드 단계여야겠다. 그럼 빠개졌으니까 테스트 서버 못나가는거에요.
그럼 그 순간에 또 누군가가 가서 테스트를 고쳐야되는구나.. 로 고치는거죠
스테이징, 프로덕션 나가는 과정 다 똑같애요
디플로이나 빌드과정 도중에 "야 나 스테이징 나가야 되니까 이 세팅 내놔", "어? 나 이 엔트리 없는데?" 404라던가 400이라던가 뱉어요. REST로 오면은 "야 나 그 세팅 밸류 못받아갖고 빌드 못했어 뽀개졌어"
그러면 누군가는 또 가서 고쳐야되. 그러면 일단 제가 아까 말했던 세팅이 없는데 잘못나가는 경우는 다 고쳐져요.
여기서 한가지 재밌는거는 결과적으로 이 모든 데이터 웹 거기에(매니저) 집어넣는 데이터가 저희 관리 툴에서 DB에 저장이 될거 아니에요? 그죠?
그러면 스테이징하고 프로덕션에 있는걸 DB에 저장을 하면은 역시 그 DB에 권한이 누구에게 있느냐에 따라, DB가 노출이 될 수 있어요.
그 DB가 털리는 경우도 있고, 그래서 한가지 더 생각을 했던게 뭐냐하면
이 스테이징하고 프로덕션에 들어가는 세팅들은 DB가 아니라 Azure Key Vault에 들어가게 하자
애져 자체에서 이런 secret information을 저장을 할 수 있게 하기 위해 그런 Encryption 다 해주고 그걸 잘 해놓은게 있어요
물론 이제 접근할 때나 또 어떤.. 로그인하고 패스워드를 따로 쳐야되지만..
어쨌든간에, 이런 비밀 정보들이 저장을 해 놓고, 그리고 그 비밀 정보를 불러오는 키 하나 정도는 아까 말했던 Environment Variable에 박으면 되니까 관리 툴에서만. 관리툴.
그러면은 DB가 털려도 우리는 테스트하고 로컬DB 정보밖에 안 털리는 거고 심지어는 잘못해서 우리가 다른 개발자에게 DB Access를 줬더라도 이 사람은 읽을 수 있는거는 테스트하고 로컬 환경밖에 없는거에요.
그러면 Prod에 필요한 정보들은 '모두' 다 다시한번 더 Encryption 된 Key Vault에 들어가 있는거죠
실제 빌드 서버는 그러나, 모르죠. 빌드 서버는 빌드 하면서 "야, 나 프로덕션 키 내놔, 이거 내놔". Hit 했어.. 응? 그래? 다 있어? 하면 받는거야. 근데 그 데이터 오는건 DB가 아니라 Azure Key Vault에서 온다는 거죠.
그러면 이것만으로 세팅이 뭔가 없거나, 빠졌을때죠 잘못된거보다는, 빠졌을 때 나갈 수 있는건 다 막은거에요.
그냥 Fail이 되기 때문에 못나가요. 그럼 누군가는 가서 고쳐야되.
여기서 한 가지 더 보너스가 있어요. 한 가지 더 보너스가. 아까 말했던 유저 시크릿 있잖아요?
제가 로컬에서 개발할 때 유저 시크릿 다 이렇게 쳐 넣어야 된다. 그런 얘기 했잖아요?
근데 유저 시크릿도 간단해져요. 그냥
똑같은거에요. 내가 테스트 환경 받아오는거나, 뭐 받아오는거나 똑같아요.
URL로 쏴 갖고, REST로 쏴갖고, 야 나 로컬에서 쓸거 내놔 이걸 유저 시크릿에 복붙해놓던가.
아니면 웹 대시보드 가서 야 나 유저 시크릿을 json 파일 다운받을게, 클릭. 하면 다운받으면, 그걸 유저 시크릿으로 옮겨갖고 쓰거나
그럼 이거를 하면은
저희가 아까 썼던 환경변수를 다 뺄수가 있어요. 다 뺄수가.. 아마 Key Vault 정도 어딘가 들어있는게 전부일거고.
모든 환경은 이제 우리 Setting Manager - 내부 툴에서 하는 거다
그러나 세팅 매니저에 가서 한땀 한땀 키 넣기 귀찮으니까 아까 말했던 json 파일 작업하면서 계속 추가하는 거니까 그걸로 key 다 채워 넣고 Default 값 채워넣고 나머지만 환경별로 설정해주게 하거나, 그렇게 한다.
이걸 이제 다 디자인을 하고 "아 잘됐어 너무 좋아"(박수) 이렇게 생각하고 있어요.
이게 제 생각에는 클라우드가 좀 더 발전하거나, 이런 닷넷코어에서 좀 더 신경을 써주거나 이러면 이렇게 좀 더 쉽게 관리할 수 있는 방법이 점점 나올거에요. 나올거에요.
그러나 아직은 이게 완성이 안된 부분이고, 닷넷코어 쪽은 DB Connection 이건 되게 쉽게 잘 되요. 근데, 아까 말했던 Environment Variable 이런게 잘 안돼있고.
이게 어찌보면은 CI에서 Continuous Integration에서 더 신경써야 될 부분이기도 해요. 왜냐하면은 Continuos Integration이라는게 코드 넣고, 다 테스트 돌리고 나가는 거잖아요.
그리고 뭐가 잘못되면은 실패하고
물론 그 모든 테스트가 완벽할 순 있지만, 새로운 기능을 추가하고 그 테스트가 없는 경우도 있어요.
그건 코드리뷰의 문제라고 하겠지만, 어차피 코드리뷰는 바쁘면 누군가는 실수도 하게 되는거고 안보는거에요.
새로운 기능을 넣고 거기에 따른 새로운 세팅이 필요해, 근데 그 세팅을 확인하는 테스트가 없었다면은? 패스해서 라이브에 나갔다가 뭔가 안돼갖고.. 나중에 깨달을 수도 있거든요
지금 보면은, 지금 이제 이 제가 만들어놓은 프로세스 자체가 복잡하지가 않아요. 만드는건 좀 귀찮지만..
한 번 만들어두면은 사용하는 사람 입장에서는 실수가 나오면 빨리빨리 잡아주니까 좋아요. 그렇다고 개발 속도가 느려지지도 않아. 오히려 빨리질수도 있어요. 로컬세팅 다운받는거때문에..
그럼 이 프로세스가 잡히면은 이제 실수를 덜할 수 있고, 빨리 잡을 수 있다는거죠
이게 좀 정형화가 됐으면 좋겠어요. 정형화가. 이걸 정형화를 잘하면 CI도 자유로워 지니까
아마 CI를 하고 있는 사람중에 이 부분을 아직 고민을 안 하는 사람이 있다면, 정말 CI를 제대로 고민 안 한 사람인거같아요.
아니면은 단순하게 "나는 모든 테스트가 완벽할거야"라는 이상한 망상을 가지고 있거나.
그래서 제가 한 번 트위터에도 썼지만 CI를 고민하는 사람중에 환경에 따라 달라지는 appsetting을 어떻게 처리한거고 어디서 실수를 어떻게 잡을 지를 고민 안하는 사람이 있다면 그거는.. 그냥 수박 겉핥기 식으로 가는 거 같다라는 얘기를 제가 했거든요.
그얘기에요
근데 당연히 전 회사에서도 봤던 문제점이고, 어느 회사에서도 봤던 문제점인데, 아직 이 부분에 대해서 그렇게 좀 깔끔하게 정리해서 나온 자료라던가 누군가 얘기하는거를 본 적이 없어요.
그래서 그냥 저도, 가내수공업으로 저만의 방법을 만든거고, 혹시라도 여기에서 제 방법보다 나은 방법을 알고계시는 분이 있다면 댓글같은거 남겨두시면..
제가 열심히 카피해갈게요(웃음)
오늘은 좀 얘기가, 모르겠어요 제가 처음부터 과연 이거를 얘기를 잘 할 수 있을까를 고민하면서 시작헀는데, 그 고민이 있었던만큼 주저리주저리 한 30분을 떠든거같고.
제가 말한 과정이 좀 이해가 잘 됐으면 좋겠는데, 모르겠네요. 설명을 잘 했는지..워낙 중구난방이라(웃음)
예, 포프였습니다.