[컴] AWS snapshot archive 정보

 

스냅샷

AWS snapshot archive 정보

금액

금액 정보 : Archive Amazon EBS snapshots - Amazon Elastic Compute Cloud

  • snapshot 금액 : 월 GB당 $0.05
  • archived snapshot
    • 월 GB당 $0.0125
    • 100 GB, 월 $1.25(100GiB * $0.0125)가 청구
  • 복원비용 : 데이터 GB당 0.03 USD
    • 100GiB 스냅샷을 복원하면 3달러 청구(100GiB * $0.03).
    • 1회성 비용
  • snapshot 이 standard tier 로 복원된 뒤로는 snapshot 요금인 월 GB당 $0.05

[컴] terraform 에서 for_each에서 map 에 list 를 감싸는 이유

 테라폼 코딩 / 꼼수 / 트릭 /

terraform 에서 for_each에서 map 에 list 를 감싸는 이유

다음 module code를 보다가 궁금한게 생겼다.

code from : https://github.com/terraform-aws-modules/terraform-aws-alb/blob/a1a54c5b0a26919eda7bdd50da6b9eed5fedcc1c/main.tf#L343

resource "aws_lb_listener_rule" "redirect_to_https" {
  # rules = { <each.key> = each.value }
  for_each = local.rules

  ...

  dynamic "condition" {
    for_each = try(each.value.conditions, [])

    content {
      dynamic "host_header" {
        for_each = try([condition.value.host_header], [])

        content {
          values = host_header.value.values
        }
      }
    }
  }

  ...
}

위코드의 input은 다음과 같다.

...
  conditions = [{
    host_header = {
      values = ["/onboarding", "/docs"]
    }
  }]
...

여기서 왜 아래처럼 condition.value.host_header를 iterate 할 때, condition.value.host_header로 감쌌는지 궁금했다.

...
      dynamic "host_header" {
        for_each = try([condition.value.host_header], [])
        # 여기서 host header 는 아래와 같다.
        # host_header = { values = ["/onboarding", "/docs"] },

        content {
          values = host_header.value.values
        }
      }
...

아래처럼 바로 map 을 이용할 수도 있는데 말이다.

...
      dynamic "host_header" {
        for_each = try(condition.value.host_header, {})
        # 여기서 host header 는 아래와 같다.
        # host_header.key = values, host_header.value = ["/onboarding", "/docs"]

        content {
          values = host_header.value
        }
      }
...

input 에서 map 의 특정key 를 사용하게 하도록 하기 위해

이것은 host_header.values 를 명시적으로 하기 위함인 듯 하다. 아래 input 값을 가지고 test 를 해보면 이해가 쉽다.

...
  conditions = [{
    path_pattern = {
      vals = ["/onboarding", "/docs"]
    }
  }]
...

만약 map을 그대로 이용한 경우에는 values를 사용하지 않아도, 첫번째 item 이 가지고 있는 값을 사용하게 된다. 하지만 list 로 감싸면, iterate 에서 map 을 그대로 사용하게 되기때문에, 명시적으로 values 를 사용해줘야만 한다.

그로인해 input 은 ’values’라는 key 를 사용해야 만 한다.

[컴] 무한스크롤 vs pagination

비교

무한스크롤 vs pagination

ref.1 은 infinte scroll 과 pagination 의 비교한 글이다.

일부를 정리하면 다음과 같다.

  • 좀 더 목적이 있는 글에는 pagination 이 낫다.

  • 유저가 빠르게 소비하는 content 에는 infinite 이 낫다.

  • 구글 search 의 결과는 pagination 이지만, google image 의 결과는 infinite 인 이유가 image 를 보는 속도가 빠르기 때문이다.

예외 상황

모든 페이지의 모습이 ref.1 의 글안에 들어맞는 것은 아니다.

몇몇 무한스크롤은 명시적으로 콘텐츠를 더 불러오기 위해 클릭을 필요로 한다.

  • 덕덕고의 검색 결과는 infinite 이다.
  • 덕덕고에서는 페이지 이후에 명시적으로 다음 페이지 로드를 하도록 한다.
    • 이것은 footer를 보여줄 수 있다.
    • 다만 여전히 클릭을 해야 한다.

개인적인 생각

개인적으로 무한스크롤의 가장 큰 단점은 명시적으로 그 곳을 찾아가기가 어렵다는 것이라고 생각한다.

그것을 극복하는 방법중에 각 글에 대한 url을 제공하는 것이 의미가 있다고 본다. 이 경우 viewer에 대한 구현은 2가지가 있을 수 있다.

  • 하나는 url의 내용만 보여주는것,
  • 다른 하나는 스크롤등의 흐름안에서 그것을 보여주는 법.
    • 이것은 '텔레그램 채널'이 가장 적절한 구현의 예를 보여준다거 생각한다.

Reference

  1. UX: Infinite Scrolling vs. Pagination

[컴] MariaDB에서 binaray logging 이 되어 있다면, trigger 를 만들때 super 권한이 필요하다.

aws mysql / aws mariadb

MariaDB에서 binaray logging 이 되어 있다면, trigger 를 만들때 super 권한이 필요하다.

"You do not have the SUPER privilege and binary logging is enabled" 

자동 백업 기능(automated backups)은 MySQL에 대해 바이너리 로깅(binary logging)을 켤지, 끌지를 결정한다.

  • 바이너리 로깅 on: 백업 보존 기간(backup retention period)을 0이 아닌 양수 값으로 설정한다.
  • 바이너리 로깅 off: 백업 보존 기간을 0으로 설정한다.

자동백업을 활성화하는 법: Working with backups - Amazon Relational Database Service

  • Creating triggers with binary logging enabled requires SUPER privilege | Troubleshooting for Amazon RDS - Amazon Relational Database Service

    • 바이너리 로깅(binary loggin)이 활성화된 경우 trigger를 사용하려면 SUPER 권한이 필요하다.
    • 이 권한은 RDS for MySQL 및 RDS for MariaDB DB instance에서는 제한이 되어있다.(참고로, 자동으로 만들어지는 user 계정도 SUPER 를 가지고 있지 않다.)
    • SUPER 권한이 없어도 log_bin_trust_function_creators 매개 변수를 true로 설정하여 binary logging이 활성화된 상황에서 trigger를 만들 수 있다.
    • log_bin_trust_function_creators를 true로 설정하려면 새 DB parameter group을 생성하거나 기존 DB parameter group을 수정하면 된다.
      (참고로, 이미 RDS 가 run 하고 있을때 수정했다면, reboot 이 필요할 수 있다.)

현재 RDS 의 binray logging 이 활성화됐는지 확인

현재 RDS 의 binray logging 이 활성화됐는지는 다음 query 로 알 수 있다.

show global variables like 'log_bin'; 

version 확인

참고로 binary log 가 활성됐을 때 db version 을 확인하면 아래처럼 ‘-log’ 가 붙어서 보인다.

-- binary loggin on
> select version();
'10.6.10-MariaDB-log'

-- binary loggin off
> select version();
'10.6.10-MariaDB'

[컴] terraform 에서 ebs block 을 추가하고, user_data 사용하는 예시

디버그 요령 / 테라폼 요령 /

terraform 에서 ebs block 을 추가하고, user_data 사용하는 예시

data "template_file" "my_user_data" {
  # template = file("../../scripts/init-fish.yml")
  template = templatefile(
    "../../scripts/init-fish.tftpl",
    {
      bashrc  = "${indent(6, file("../../scripts/.bashrc"))}"
    }
  )
}


output "debug_user_data_output" {
  value = data.template_file.my_user_data.rendered
}

resource "aws_instance" "stage_a" {
  ...

  user_data = data.template_file.my_user_data.rendered
}

resource "aws_ebs_volume" "stage_a" {
  availability_zone = "ap-northeast-2a"
  size              = 10 # GB
  iops              = 3000
  type              = "gp3"
}

resource "aws_volume_attachment" "ebs_att" {
  device_name = "/dev/sdf"
  volume_id   = aws_ebs_volume.stage_a.id
  instance_id = aws_instance.stage_a.id
}
#cloud-config

packages:
  - curl

# .bashrc file
write_files:
  - path: /home/admin/.bashrc
    content: |
      "${bashrc}"
  - path: /home/admin/.profile
    content: |
      if [ -n "$BASH_VERSION" ]; then
          # include .bashrc if it exists
          if [ -f "$HOME/.bashrc" ]; then
              . "$HOME/.bashrc"
          fi
      fi

bootcmd:
  # format 하고
  - test -z "$(blkid /dev/nvme1n1)" && mkfs -t ext4 -L home_admin /dev/nvme1n1
  - mkdir -p /home/myuser

mounts:
  # mount
  - [ "/dev/nvme1n1", "/home/myuser", "ext4", "defaults,nofail", "0", "2" ]

runcmd:
  # set .bashrc
  - cp -f /home/bashrc_template_by_cloud_init /home/myuser/.bashrc
  - chown admin:admin /home/admin/.bashrc
# .bashrc, ${}를 사용하려면 $${} 를 사용해야 한다. terraform 에서도 ${} 를 사용하기 때문에. 나머지 $ 들은 괜찮다.
if [ -n "$force_color_prompt" ]; then
  if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
      # We have color support; assume it's compliant with Ecma-48
      # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
      # a case would tend to support setf rather than setaf.)
      color_prompt=yes
  else
      color_prompt=
  fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='$${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$$ '
else
    PS1='$${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

data template 의 output 을 확인

다음 처럼 output 을 추가하고, terraform plan 을 하면 output 이 template_file이 어떤 모습으로 생성되는지 확인할 수 있다.

...
output "debug_user_data_output" {
  value = data.template_file.my_user_data.rendered
}

aws cloud init debug

  1. aws management console 에서 stop instance 를 한 후 Actions -> Instance settings -> Edit user data 를 하자.
  2. 수정후 start instance
  3. cat /var/log/cloud-init-output.log

/var/log/cloud-init-output.log

aws 에서 cloud init 에 대한 log는 /var/log/cloud-init-output.log 에서 확인할 수 있다.

See Also

  1. 쿠…sal: [컴] aws 에서 cloud-init 을 이용해서 ebs attach

Reference

  1. grep - How to escape special characters in Terraform local-exec command line - Stack Overflow

[컴] aws 에서 cloud-init 을 이용해서 ebs attach

 

aws 에서 cloud-init 을 이용해서 ebs attach

aws 에서 ebs block 을 attach 하는 경우, instance 가 생성된 후 로그인을 하고, mkfs 를 해줘야 한다.

이것을 cloud-init 을 통해 해보려 했다.

ref. 2 에서 이야기처럼, 문제는 instance 가 run 되고 나서 ebs 가 인식되는 듯 하다. 그래서 cloud-init 시점에 mount 나 mkfs 명령어가 제대로 동작하지 않았다.

그래서 결론은 runcmd 에 sleep 을 주는 것으로 해결했다.

첫번째 시도, disk_setup, fs_setup

fs_setup을 통한 방법은 ref.1 을 보면, 이제 amazon linux 에서도 지원한다고 한다. 그래서 일단 시도해봤다. 아래 cloud-config 에서 ‘2nd Attempt’ 대신 1st Attempt 를 사용했다.

이 경우에는 처음 실행후, 다시 cloud-init 을 하는 경우에 mount 가 됐다.

  • instance running
  • login
  • sudo cloud-init clean
  • reboot
#cloud-config

packages:
  - curl

bootcmd:
 - mkdir -p /services

# ----------------
#
# 1st Attempt
#
# ----------------
# disk_setup:
#   /dev/nvme1n1:
#     table_type: gpt
#     layout: true
#     overwrite: false
#
# fs_setup:
#   - label: fs1
#     filesystem: ext4
#     device: /dev/nvme1n1
#     partition: auto
#     cmd: mkfs -t %(filesystem)s -L %(label)s %(device)s
#
# mounts:
#  - [ "/dev/nvme1n1", "/services"]

# ----------------
#
# 2nd Attempt
#
# ----------------
runcmd:
  - chown -R admin:admin /home/admin/
  - sleep 1m
  - test -z "$(blkid /dev/nvme1n1)" && mkfs -t ext4 -L fds1 /dev/nvme1n1
  - mount /dev/nvme1n1 /services
  - echo '/dev/nvme1n1  /services auto defaults,nofail,comment=cloudconfig 0 2' >> /etc/fstab

2번째 시도, sleep 1m

약 1분 정도 sleep 을 줬다. 참고로 sleep 중에도 ssh login 은 가능했다.

이 경우 정상적으로 mount 를 완료했다.

See Also

  1. cloud init debugging 방법 : Debugging cloud-init — cloud-init 22.2.2 documentation

Reference

  1. amazon linux 2023 에서 fs_setup이 가능한 듯 보인다.
  1. amazon ec2 - cloud-init: delay disk_setup and fs_setup - Stack Overflow : volume attachment 가 instance 가 완전히 실행이 된 이후에 되는 경우가 있다. 그 경우에 대한 fs_setup을 위해서 reboot 을 하게 하는 cloud-config 를 보여준다. sleep 에 대한 이야기도 여기에 있다.

[컴] terraform 에서 공통 변수 사용법

 

테라폼 / 사용법 / common / global variable /

terraform 에서 공통 변수 사용법

terraform 에서 환경변수 예시

export TF_VAR_test_var="testvar"

terraform에서 다음처럼 변수를 선언하고 사용하면 된다.

variable "test_var" {
    type        = string
    description = "This is an example input variable using env variables."
    default = "testvar"
}

resource "aws_instance" "tf-dev-auth-c" {
  tag = {
    test = var.test_var
  }
  ...
}

See Also

  1. 쿠…sal: [컴] Terraform 사용법