개발 회고


배경

회고를 작성하다 보니 내용이 많아서, 따로 글을 작성하게 되었다.


개발 사례 회고

내용

아래 내용들은 회고에 이미 적었던 부분이며, 관련해서 형식 없이 이야기하고 의식의 흐름대로 적어보려고 한다.

  • 일반화 및 표준화의 중요성
  • 어딘가에는 흔적을 남겨 놓아야 한다.
  • 기술이 다가 아니다.
  • 리소스만 믿고 의존하면 안 된다.
  • 우려한 건 언젠가는 발생할 수 있다.
  • DEV, STG, PROD의 구분은 중요하다.
  • 테스트는 너무도 중요하다
  • 사람을 믿지 말자.
  • 바쁘더라도 필요한 건 해야 한다.
  • 컨텍스트 체인지에는 많은 시간이 든다.
  • 높은 조직의 정책과 당시 상황의 영향
  • 체력이 튼튼하고 정신을 똑바로 차려야 한다.


일반화 및 표준화의 중요성

회사 Big Data센터에 오면서 전사 데이터에 관한 일을 해왔다. 여기에 와서 가장 크게 느꼈던 부분이 일반화 및 표준화의 중요성이다. 그 반대가 파편화다.

일하는 곳이 전사 조직이 되면서, 전사 데이터를 수집하는 시스템을 만드는 과제를 받았다. 그런데 그 과제를 진행하기에 앞서 이전에 진행했던 과제들을 살펴보았는데, 많은 고생이 있었던 것이 눈에 띄었다. 대표적으로 서비스별로 수집하는 방식이나 포맷이 서로 달랐고, 이러한 부분이 하나로 일원화되지 않은 채 진행된 상황이었다. 글을 읽으면서 “왜?”라고 의문을 가질 수 있다. 그런데 그렇게 된 이유는 분명 있었을거라 생각한다.. 그 이유를 모두 알지는 못하지만, 관련된 추가 이야기는 뒤에 적겠다.

표준화와 일반화가 이루어지지 않으면 파편화가 발생하고, 서비스가 커질수록 그것을 관리하고 유지하는 것이 굉장히 힘들어진다는 것을 경험했다. 서비스가 커질수록 표준화와 일반화는 필수적이라고 생각한다.

리더나 매니저급에서는 단순히 과제를 완수하는 것에 그치지 않고, 최대한 일반화하여 그에 맞추도록 노력해야 실무가 덜 힘들고 품질도 개선될 수 있다고 생각다. 기존에 만들어 놓은 플랫폼이 있는데, 협업하는 곳이 요구하는 대로 모두 맞춰주면 그것은 SI 업체일 뿐, 진정한 협업이 아니라 본다. 물론 어느 정도 이유가 있을 수 있고, 그 의견을 듣고 방법이 하나밖에 없다면 미루거나 하면 되지 않나 싶다.

작은 서비스이고 사람이 관리하기 쉬운 10개? 이하는 문제가 없지만 그 이상이면 플랫폼 성격을 가졌다면 일반화 및 표준화가 중요한 거 같다. 큰 플랫폼이라면, 힘과 영향력을 가진 상위 부서에서 일반화 및 표준화를 위한 방향을 설정하고 가는 것이 맞다고 생각한다.


어딘가에는 흔적을 남겨 놓아야 한다.

특정 기능을 개발한 사람이 평생 관리한다면 이 이야기는 필요 없겠지만, 프로그램과 달리 사람은 언제든 바뀔 수 있다. 그렇기에 어떤 작업을 왜 했는지 기록으로 남겨두는 것이 중요하다는 것을 몸소 체감했다. 그 방법은 여러 가지가 될 수 있다. 문서로 정리해서 남겨두거나, 코드에서는 주석이나 함수명을 자세히 작성하는 방식이 있을 수 있다. 주석을 다는 것이 코드로 충분히 표현하지 못한 것을 보완하는 방법이라 좋지 않다는 말을 들었지만, 코드로 표현할 수 없다면 주석이라도 남겨두어야 다. “왜 이렇게 되어 있는 거지?”라는 질문을 담당자가 찾아가서 직접 설명을 듣는 시간을 아낄 수 있고, 담당자가 없을 때도 대처할 수 있다.

코드에 의도를 최대한 표현하고, 그렇지 않으면 문서나 다른 곳에 표시를 해두는 것이 팀의 효율성을 위한 일이다.

실제로 올해 너무 바빴던 나머지 이런 상황이 가끔 있었고, 내가 겪은 적도 있었기에 이제는 최대한 기록을 남기는 습관이 생겼다.


기술이 다가 아니다.

올해 [회고] 상반기 회고에도 기록했던 내용이다. 크게 달라진 점이 없어 그대로 가져왔다.

기술이 다가 아니다. 10분 만에 해결될 일이 감정 문제로 10일이 걸릴 수도 있다. 개발은 완료되었지만, 서비스 측에 갑자기 생긴 프로세스로 업무가 늘어난 사례가 있었다. 실무자의 협조가 어렵다고 한 부분을 매니저 또는 더 위에 상급자의 도움을 받아서 더 빠르게 해결한 경우도 있었다. 이렇듯 때로는 개발만이 아닌 사람을 통해서도 문제가 해결될 수 있는 거 같다.


리소스만 믿고 의존하면 안 된다.

큰 서비스 개발 경험이 부족해서 그럴 수도 있지만, 개발하다 보면 리소스를 믿는 경향이 있었다. 예를 들면 코드 작성 시 메모리가 충분하다고 생각해 개발했는데 OOM(Out of Memory) 오류가 발생한 경우가 있었고, 옵션을 지나치게 줘서 OOM 오류가 발생한 적도 있었다. 메모리의 예시만 들었지만, 스토리지뿐만 아니라 서비스가 커지면서 네트워크나 데이터베이스에 부하가 걸려 이슈가 발생했던 경험도 있다.

Pod를 실행하면서 OOM 오류가 발생했고, Airflow에서 데이터베이스에 많이 접근하다 보니 병목이 생겼다. 또 인프라 구축 시 옵션을 너무 크게 설정하여 Pod가 죽는 경우도 있었다. 물론 응답 결과가 너무 느리거나 많아서 Swagger에서 응답 없는 상태가 되었던 적도 있다. 서비스가 커지면서 AWS Quota에 걸려 늘려달라고 요청한 경우도 많았다.

초기에 개발 시에는 메모리 신경 쓸 여유가 없지만, 서비스가 커지면서 문제가 터질 수 있다는 점을 항상 염두에 두어야 하고, 가능하다면 미리 대비하는 것이 좋다.


우려한 건 언젠가는 발생할 수 있다.

“아… 이거 나중에 문제가 될 수 있을 것 같은데?”라는 생각이 들었던 부분이 실제로 발생한 경우가 있었다.

클라우드에서 자동으로 생성되는 부분이 있었는데, 좀 포괄적으로 제외해 놓고 나중에 수정했던 경험이 있다. 이 경우, 문서에도 없고 좀 이상하게 만든 것 같다는 의견이 있었지만, 그래도 우려했던 문제가 발생했던 사례였다. 또 다른 사례로는 인프라 구축 설정값을 하나로만 관리하다가, 서비스가 커지면서 배포가 느려지고 관리가 어려워질 것 같았는데, 담당자가 고생해서 이를 바꿔준 경험이 있다.

너무 당연하고 모두가 아는 이야기지만, 한 번 더 염두에 두고 미리 해결하면 좋을 것 같아서 적어봤다. 물론 일을 하다 보면 그것이 쉽지 않지만… 하하. 적절한 타협은 당연히 필요하다.


DEV, STG, PROD의 구분은 중요하다.

개발하는 컴포넌트가 많아짐에 따라 환경 구분의 중요성을 몸소 체감했다.

테스트를 진행하면서 내가 개발한 것과 다른 사람이 개발한 부분이 충돌하거나, 통합 테스트 중에 이슈가 발생하곤 했다. DEV/STG 환경이 일부 겹쳐 있어서 발생한 일이었다.

너무도 당연한 이야기지만, 신규 과제를 진행하는 환경에서는 발생할 수 있기에 적어봤다.


테스트는 너무 중요하다

올해 테스트 및 CI/CD 업무를 맡아 진행했는데, 테스트가 있을 때와 없을 때 품질의 차이와 불안함의 체감 정도가 너무 달랐다.

단위 테스트와 통합 테스트가 있었기 때문에 배포할 때 마음이 많이 놓였다.

품질을 높여주고 사람들을 불안하지 않게 해주는 점에서 큰 매력을 느꼈다.

너무 바쁘다 보니 테스트 작성할 시간이 없다는 건 이해하지만, 그래도 테스트만큼은 꼭 작성하는 게 맞다고 생각한다. 나중에 개발할 때도 반드시 도움이 된다.


사람을 믿지 말자.

오해할 수 있지만, 사람이 나빠서 믿지 말자는 이야기가 아니다. 사람이 실수할 수 있기 때문에 사람에게만 의존하면 안 된다는 이야기다.

협업 중에 사람이 직접 매일 작업을 해주겠다고 했던 곳이 있었는데, 결국 이슈가 생기고 연쇄적으로 스트레스를 받았던 기억이 있다. 최근에도 데이터를 수집해야 하는데 데이터를 올려주지 않거나 다른 포맷으로 주는 경우가 있었기에, 직접 데이터를 수집하는 쪽에서 데이터에 직접 접근할 수 있도록 시스템을 만드는 것이 맞다고 생각한다.

결국 모든 것은 자동화해야 하는 것이 맞다. 서로를 위해 시스템화해야 서로가 편하다. 데이터 파이프라인을 만든다고 가정할 때, 데이터베이스에 직접 접근하는 것부터 적재까지 하나의 팀에서 모니터링할 수 있어야 소통이 줄어든다. 또 다른 예로, 비밀번호나 정보를 사람이 직접 입력하면 실수가 있을 수 있기 때문에 검증을 입력한 사람이 직접 하도록 시스템을 만들어야 한다. 마지막으로, 사람이 테스트를 모두 했더라도 최종 테스트는 기계에 의해 진행되어야 품질을 확실히 보장할 수 있다.


바쁘더라도 필요한 건 해야 한다.

위에서 언급한 내용과 일부 겹치긴 한다. 이 부분도 타협의 영역이고 상황에 따라 달라질 수 있지만, 테스트처럼 중요한 부분은 최대한 시간을 내서 해야 한다.

마이그레이션을 하면서 사용하던 옵션을 빠뜨려서 큰 용량의 값을 처리해야 하는 상황이 있었다. 이를 계속 미루다가 결국 용량이 너무 커져 이슈가 발생했다. 반드시 일어날 것 같고 해야 할 것 같다는 강한 의심이 든다면, 바쁘더라도 지금 해결하는 게 좋다. 서비스 측에도 관련된 부분이라 미리 해야 일이었다.

역시 말처럼 쉽지 않다는 걸 아주 잘 알고 있다.


컨텍스트 체인지에는 많은 시간이 든다.

여기서 말하는 컨텍스트 체인지란 업무의 변경을 의미한다. 맡은 업무가 변경될 수도 있고, 해야 하는 일이 바뀔 수도 있다.

올해 잦은 인터럽트로 인해서 하던 일이 자주 바뀌었고, 정신이 없었으며 일을 재개할 때 집중하기 어려웠다.

상반기에 업무 분장을 새로 했는데, 바쁜 와중에 새로운 업무를 시작하니 다시 익히는 데 시간이 많이 소요됐다. 이렇듯 업무가 변경되면 익히는 데 시간이 많이 드는 것 같으므로, 그런 계획이 있다면 충분한 버퍼를 두는 게 좋을 것 같다.


높은 조직의 정책과 당시 상황의 영향

일을 하다 보면 “왜 저렇게 만들었을까?”라는 질문을 종종 한다. 내가 더 잘 만들 수 있을 것 같다는 자만에서 나오는 질문이 아니라, 조금 돌아서 만드는 느낌을 받을 때가 있었다. 위에서 언급한 파편화가 된 것도 비슷한 맥락이다. 그래서 당시 담당자들과 이야기해 보면 다 이유가 있었다. 팀의 힘이 부족해서 정치나 권력 문제로 상대방에 맞춰야 했던 경우도 있고, “이렇게 안 하면 안 해준다”라는 식의 상황도 있었다. 요구사항이 매번 달라졌고, 일반화가 안 되었으며 여러 가지 이유가 있었다. 이렇듯 당시의 개발 외적인 외부 상황에 따라 개발이 영향을 받아 어려운 방향으로 가는 경우가 있다. 엔지니어가 놓치거나 못한 부분일 수도 있지만, 외부의 영향이 큰 경우도 있다.

파편화된 상황에서 전사 조직으로 바뀌고, 조직 내 힘 있는 리더가 전사에 공표하니 누구나 해야 할 일이 되어서 모두가 대응해 줬다. 기술이 뛰어나도 전사 차원에서 밀어주지 않으면 진행되지 않았을 것이다. 이렇듯 힘 있는 조직에서 정책을 만들어야 일이 진행된다는 것을 경험했고, 그게 맞는 방향이라고 생각한다. 상무급에서 협의하는 것보다 사장급에서 전사에 지시를 내리는 게 훨씬 효율적이다.


체력이 튼튼하고 정신을 똑바로 차려야 한다.

체력은 아무리 강조해도 부족할 정도로 중요하다. 체력이 있어야 집중할 수 있다. 체력이 떨어지면 집중력도 떨어지고 효율도 나지 않는다. 체력이 부족하면 어떤 일이든 효율이 떨어지게 된다.

이전에는 이슈가 발생해도 큰 문제가 되지 않았지만, 이제는 연관된 서비스가 매우 크고, 사용자가 많아 실수가 나면 안 되는 상황이기 때문에 매번 집중해서 일을 했다.

이슈 발생 시 영향이 큰 경우 실수하면 안 되므로 정신을 차려야 한다. 이를 받쳐주려면 체력이 필요하다.


마무리

이 모든 이야기는 올해 느낀 부분으로, 좀 더 자세히 적어서 더 많은 공감을 얻고 싶었지만 회사 관련된 이야기가 많아 세세히 쓰지 못한 것이 아쉽다. 그런데도 제목과 내용을 읽으면서 충분히 공감할 수 있는 사례가 많을 것으로 생각한다. 물론, 이러한 사례들은 상황에 따라 달라질 수 있기 때문에 언제나 유연하게 사고하고 대처해야 한다. 당연히 정답은 아니다.

일을 하면서 몸과 마음이 고생했지만, 그럼에도 몇 가지 배운 점이 있어 긍정적으로 생각한다.

Development Retrospective


Background

I made another post because retrospective already has long contents so I extract this post from there.


Development Case Retrospective

Contents

I’ve already included the content below in the retrospective, and now I want to write freely, following the flow of thoughts without any specific format.

  • The importance of generalization and standardization.
  • Traces must be left somewhere.
  • Technology is not everything.
  • Resources cannot be completely trusted.
  • What you worry about can happen someday.
  • Distinguishing between DEV, STG, and PROD is important.
  • Test is very important.
  • Don’t trust people.
  • Even when busy, you must do what’s necessary.
  • Context switching takes a lot of time.
  • The policies of high level organizations and the circumstances at the time.
  • You need to maintain physical strength and stay mentally focused.


The importance of generalization and standardization.

Since joining the Big Data Center of the company, I have been working on projects related to company wide data. One of the most significant realizations I’ve had here is the importance of generalization and standardization. The opposite of these is fragmentation.

As I became part of an enterprise level organization, I got a task which creating a system to collect data across the company. However, before proceeding with this task, I reviewed previous projects and noticed the challenges that had been encountered. A major issue was the lack of consistency data collection methods and formats differed across services, and these discrepancies had not been unified. While reading this, you might ask, “Why?” There were likely reasons for this, even though I may not know all of them. I’ll share more thoughts on this later.

Through my experience, I’ve learned that when standardization and generalization are not achieved, fragmentation occurs. As a service grows, managing and maintaining it becomes increasingly difficult. I believe that standardization and generalization are essential as services expand.

For leaders or managers, it’s not enough to simply complete a project; they should aim to generalize as much as possible to ease the workload for workers and improve quality. If you just adapt entire demands of collaborating parties, it would be a SI not a collaboration. Of course, there might be valid reasons to consider such requests, but in cases where there’s no alternative, I think it’s better to postpone or make adjustments rather than applying everything.

For small services that are easy to manage such as under ten systems, fragmentation may not pose much of an issue. However, when the service exceeds this scale and takes on the characteristics of a platform, generalization and standardization become crucial. In the case of a large platform, I believe it is appropriate for a higher level department to set the direction for generalization and standardization.


Traces must be left somewhere.

If the person who developed a specific feature were to manage it for life, this discussion might not be necessary. However, unlike programs, people can change at any time. This has made me realize firsthand the importance of documenting why certain tasks were done. There are various ways to do this: organizing it in a document, or leaving detailed comments and function names in the code. While some argue that comments are not ideal as they compensate for what code fails to express, if something cannot be conveyed through code, leaving comments is still necessary. This can save time by avoiding the need for a new person to ask, “Why is this done this way?” and having to track down someone to explain. It also allows for handling situations even when the person in charge is unavailable.

Expressing intent as much as possible in the code and documenting it elsewhere when that’s not feasible is crucial for team efficiency.

This year, there were times when I was so busy that such situations occurred occasionally. Having experienced it myself, I’ve now developed a habit of leaving records as much as possible.


Technology is not everything.

This is something I also documented earlier this year in my retrospective: [Retrospective](EN) The first half retrospective). Since there haven’t been any major changes, I’ve brought it over as is.

It’s not all about technical skills. Something that could be resolved in 10 minutes technically might take 10 days due to emotional issues. There was a case that work time becomes longer due to newly created process in service part even though development were done. There was a case that owner told us that they cannot corporate but we asked to high level manager to corporate it. After that issue was solved. It seems that sometimes problems can be resolved not only through development but also by communication with people.


Resources cannot be completely trusted.

It could be due to my lack of experience in developing large scale services, but I’ve noticed a tendency to trust resources while developing. For example, I once assumed there was sufficient memory when writing code, only to encounter an OOM (Out of Memory) error. In another instance, an OOM error occurred because I set the options excessively. Although I’ve used memory as an example, I’ve also faced issues with storage, as well as load related problems on the network or database as the service grows.

For instance, I experienced OOM errors while running Pods and bottlenecks caused by frequent database access in Airflow. There were also cases where Pods crashed because options were set too big during infrastructure setup. Additionally, responses were either too slow or too large, causing Swagger to become unresponsive. As the service scaled, there were several instances where we hit AWS Quotas and had to request increases to AWS.

While there may not be enough bandwidth to worry about memory in the early stages of development, it’s crucial to keep in mind that problems can arise as the service grows. Whenever possible, it’s better to anticipate and prepare for these issues in advance.


What you worry about can happen someday.

There were moments when I thought, “Ah… this could become a problem later,” and those concerns did, in fact, happen.

For instance, there was a part in the cloud that automatically generates resources. Initially, I excluded it more broadly and later modified it. Although there were comments that it seemed oddly configured and it wasn’t documented, the potential issue I had been concerned about actually occurred. In another case, we initially managed infrastructure setup values as a single file. As the service grows, deployments became slower, and management became increasingly difficult. Eventually, a team member took the initiative to revise and improve the system, although it required significant effort.

This may seem obvious and like something everyone already knows, but I thought it was worth emphasizing again. It’s better to address these concerns in advance if possible. Of course, it’s easier said than done in practice… haha. Finding the right balance is, of course, necessary.


Distinguishing between DEV, STG, and PROD is important.

As the number of components I developed increased, I came to realize firsthand the importance of environment.

While testing, there were cases where my work conflicted with parts developed by others, or issues arose during integration testing. These problems occurred because the DEV and STG environments partially overlapped.

Although this may seem obvious, I wanted to note it down as it’s something that can happen in new project environments.


Test is very important.

This year, I was responsible for testing and CI/CD tasks, and I deeply felt the difference in quality and the level of anxiety between having tests and not having them.

Having unit tests and integration tests provided significant peace of mind during deployments.

I found it incredibly appealing how tests not only improve quality but also reduce anxiety for everyone involved.

While I understand the argument that there’s no time to write tests because of a busy schedule, I still firmly believe that writing tests is essential. They are invaluable when it comes to future development.


Don’t trust people.

It might be misunderstood, but this is not about saying that people are untrustworthy. It’s about the fact that people can make mistakes, so we shouldn’t rely solely on them.

During a collaboration, there was a case where someone promised to handle tasks manually every day, but eventually issues arose, causing a chain reaction of stress. Recently, there have also been instances where data wasn’t provided or was given in a different format when it needed to be collected. In such cases, I believe it’s better to build a system that allows the team to directly access database.

In the end, everything should be automated. It’s better for everyone if we systematize tasks for mutual convenience. For example, when building a data pipeline, a single team should be able to monitor everything from direct access to the database to data loading, which would reduce the need for communication. Another example is when people manually enter passwords or information, errors can occur, so a system should be created to allow the person entering the data to perform the validation. Lastly, even if people perform all the tests, the final testing should be done by machines to ensure quality is reliably guaranteed.


Even when busy, you must do what’s necessary.

Some of this overlaps with what I mentioned earlier. This is also a matter of compromise, and it can vary depending on the situation, but for critical areas like testing, it’s essential to make time and make them.

During a migration, I once overlooked an option, which led to a situation where I had to handle large data volumes. I kept postponing it, and eventually, the data size grew too large, causing issues. If you have a strong suspicion that something will definitely happen or is something that needs to be done, even if you’re busy, it’s better to address it right away. This was something that also involved the service side, so it should’ve been handled in advance.

Again, I fully understand that, as mentioned, it’s not easy.


Context switching takes a lot of time.

The “context change” referred to here means a change in tasks. The work you’re assigned could change, or the tasks you need to complete may shift.

This year, frequent interruptions caused me to often switch tasks, making it hard to focus and difficult to get back into the flow of work when doing again.

In the first half of the year, we reorganized our tasks, and starting new work in the middle of a busy period took a lot of time to get up to speed. When tasks change, it seems to take a lot of time to learn everything again. So, if such changes are planned, it’s a good idea to leave enough buffer time.


The policies of high level organizations and the circumstances at the time.

When working, I often ask myself, “Why was it made like that?” This question doesn’t come from arrogance, but rather from the feeling that things were made in a somewhat roundabout way. This is similar to the fragmentation I mentioned earlier. When I talked to the people in charge at the time, I found that there were reasons for everything. Sometimes, the team lacked the necessary organization power, and decisions had to be made to accommodate political or power related issues. There were also situations where it was a matter of, “If you don’t do it this way, we won’t cooperate.” The requirements were constantly changing, there was no standardization, and there were many other reasons. In situations like this, external factors beyond development can influence the direction of the project, making things harder. While there may have been areas where engineers missed or couldn’t address something, external influences played a large role as well.

When my team shifted to a larger, enterprise wide organization, and a powerful leader within the organization publicly announced a change, it became something everyone had to follow. Everyone responded. Even with strong technical capabilities, without support from the organization at the enterprise level, it wouldn’t have moved forward. From this experience, I learned that in a strong organization, policies need to be created for progress, and that’s the right approach. It’s much more efficient for the CEO to give a directive for the whole company than for an executive at the director level to try to negotiate.


You need to maintain physical strength and stay mentally focused.

Physical stamina is incredibly important, and no matter how much it’s emphasized, it still can’t be stressed enough. You need stamina to stay focused. When your energy drops, your concentration decreases, and efficiency suffers. When you’re lacking stamina, your efficiency in any task drops.

In the past, even if issues arose, they weren’t a huge problem. But now there are many services and users which mistakes are unacceptable. So, I have to stay focused every time I work.

When issues arise and the impact is significant, you can’t afford to make mistakes, so it’s important to stay alert. And to maintain that focus, you need physical stamina.


Conclusion

All of this reflects what I’ve felt this year. I wanted to go into more detail and share more specific examples to gain deeper empathy, but since many of the stories are related to the company, I couldn’t elaborate as much as I would have liked. Even so, I believe there are many relatable examples in the title and the content. Of course, these situations can vary depending on the context, so it’s important to think flexibly and respond accordingly. This are not definite answers.

While my body and mind went through some tough times, I try to think positively because there are still several things I’ve learned.

도메인의 인증서가 서브도메인의 인증서로 적용되었던 사례.


환경

  • Let’s Encrypt
  • Nginx
  • Certbot


배경

  • 궁금해서 운영하던 도메인의 인증서를 확인해봤는데 도메인의 인증서가 서브도메인으로 되어있는걸 발견하여 수정했다. 예를 들어 도메인이 twpower.org라고 하면 브라우저에서 봤을 때 subdomain.twpower.org의 인증서로 되어 있었다.
  • 사용하는 서버의 경우 Nginx를 이용하는 환경이고 certbot을 통해서 인증서 설정을 했었다.


이유

  • Let’s Encrypt의 인증서를 사용했고, certbot을 통해 설정했었는데, 확인해보니 도메인별로 따로 인증서 설정을 해야 했었다. 그런데 하나의 명령어로 서브도메인까지 함께 적용했었다.
  • 링크를 찾아보면 와이드카드로 서브도메인까지 포함해 설정이 가능했다. 그런데 방법이 조금 복잡해보여 적용하지는 않았다.


수정 방법

  • 도메인별로 각각 따로 지정해줘야 한다고 한다. 예를 들어 twpower.org 그리고 서브도메인이 subdomain.twpower.org라면 아래처럼 따로 적용하면 된다.
  • 아니면 위 링크에 있는 방법으로 서브도메인까지 적용 가능하다. 하지만 이 글에서는 다루지 않는다.
sudo certbot --nginx -d twpower.org -d www.twpower.org
sudo certbot --nginx -d subdomain.twpower.org


조치 과정

기존에 certbot에 의해 설정되었던 부분들을 제거하고 다시 인증서를 설정했다.


certbot에 의해 작성된 기존 설정들 제거

/etc/nginx/sites-enabled/에 설정 파일들이 아래처럼 도메인명으로 만들어져 있다.

twpower@twpower-private-server:/etc/nginx/sites-enabled$ ls /etc/nginx/sites-enabled/
subdomain.twpower.org  twpower.org

certbot에 의해 설정된 부분들을 아래와 같이 주석이 달려있다. 아래는 일부를 발췌했다.

if ($host = www.twpower.org) {
    return 301 https://$host$request_uri;
} # managed by Certbot


if ($host = twpower.org) {
    return 301 https://$host$request_uri;
} # managed by Certbot

기존에 적용된 부분들을 없애기 위해 # managed by Certbot로 되어있는 부분들을 모두 삭제했다.

Nginx 영향 확인

sudo nginx -t

certbot을 통해 인증서 다시 설정

nginx 설정이 정상이라면 아래 명령어를 참고하여 도메인과 서브 도메인에 인증서를 적용한다.

sudo certbot --nginx -d twpower.org -d www.twpower.org
sudo certbot --nginx -d subdomain.twpower.org


결과

  • 각 도메인으로 들어가서 인증서를 확인해보면 서로 다른 인증서가 적용되어 있다.


의견

  • 요즘에는 클라우드 서비스를 이용하면 이런 작업은 다 해주는데 또 접할 기회가 있을지 모르겠다.
  • 클라우드 서비스에서 해줄 뿐 아니라 ChatGPT 같은 서비스에서 다 자세하게 알려주는 시대라 이걸 다시 접할 기회가 올지는 모르겠다.
  • 나처럼 작은 서버 운영할 때는 도움이 될 수 있겠다.


참고자료

Case of subdomain’s certificate was applied to root domain.


Environment and Prerequisite

  • Let’s Encrypt
  • Nginx
  • Certbot


Background

  • Due to my Curiosity, I searched my domain certificate and found that domain’s certificate was configured to subdomain’s certificate so I modified it. For example, if domain is twpower.org, the certificate was displayed as subdomain.twpower.org’s certificate in browser.
  • Running server is Nginx environment and set certificate by using certbot.


Reason

  • I used a Let’s Encrypt certificate and set it up using certbot. I found that I needed to set certificate per doamin. However I set up domain and subdomain simultaneously.
  • Link shows a way of applying wildcard which contain subdomain. However I did not follow that way because it looks not easy.


Fix Method

  • Certificate setting should be applied per domain. For example if there are domain twpower.org and subdomain subdomain.twpower.org then it can be applied like below command.
  • It is possible to apply to subdomain using above Link. However this post does not include that method.
sudo certbot --nginx -d twpower.org -d www.twpower.org
sudo certbot --nginx -d subdomain.twpower.org


Fix Process

Remove exist previous setting by certbot and set certificate again.


Remove existing configurations created by certbot

There are setting files per domain in /etc/nginx/sites-enabled/.

twpower@twpower-private-server:/etc/nginx/sites-enabled$ ls /etc/nginx/sites-enabled/
subdomain.twpower.org  twpower.org

The parts configured by certbot are commented as shown below.

if ($host = www.twpower.org) {
    return 301 https://$host$request_uri;
} # managed by Certbot


if ($host = twpower.org) {
    return 301 https://$host$request_uri;
} # managed by Certbot

To remove previous exist setting, I removed codes which commented with # managed by Certbot.

Check Nginx

sudo nginx -t

Set Certificate Using certbot

If nginx configuration is correct, refer to the command below to apply the certificate to both domain and subdomain.

sudo certbot --nginx -d twpower.org -d www.twpower.org
sudo certbot --nginx -d subdomain.twpower.org


Result

  • Each domain has each own certificate.


Opinion

  • These days, cloud services handle these tasks, so I may not encounter this situation again.
  • Not only do cloud services handle this, but we also live in an era where services like ChatGPT provide detailed instructions, so I might not have the chance to encounter this again.
  • When running a small server like me, this could be helpful.


Reference

workflow_dispatch와 workflow_call을 사용하지 않을 때 기본값 설정하기


환경

  • GitHub Actions


배경

  • GitHub Actions에서 workflow_dispatchworkflow_call에 정의된 inputs을 사용하는 부분이 있었는데 이 부분이 push와 같이 다른 이유로 호출될 때 사용하지 못하는 이슈가 발생하여 기본값을 설정해두면 대처가 가능할거 같아 찾아서 정리했다.


방법

  • push와 같이 workflow_dispatchworkflow_call이 아니라서 inputs을 사용할 수 없는 경우 기본값을 설정할 수 있다.
  • workflow_dispatch 또는 workflow_call을 통해 실행된 workflow의 경우 inputs에 명시된 값을 사용하고 그렇지 않다면 || 뒤에 나온 기본값을 사용하는 방식이다.
  • 기본값을 환경변수에 저장하고 그 환경변수를 가져오는 방식이다.

코드

name: Workflow Return Test
on:
  push:
    branches: [ main ]
  workflow_call:
    inputs:
      key:
        type: string
  workflow_dispatch:
    inputs:
      key:
        type: string
jobs:
  print_default_value_test:
    name: print value
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Set default value
        run: |
          echo "VALUE_NAME=${{ inputs.key || "default value" }}" >> $GITHUB_ENV
      - name: Print value
        run: echo "${{ env.VALUE_NAME }}"

결과

  • push를 통해 실행된 경우
Run echo "default value"
  echo "default value"
  shell: /usr/bin/bash -e {0}
  env:
    VALUE_NAME: default value
default value
  • “test input value”라는 문자열 값을 전달해 workflow_dispatch 또는 workflow_call을 통해 실행된 경우
Run echo "test input value"
  echo "test input value"
  shell: /usr/bin/bash -e {0}
  env:
    VALUE_NAME: test input value
test input value


의견

이렇게 하는게 권장하는 방법인지는 모르겠으나 검색했더니 나온 결과가 있어서 사용했다.


참고자료