2018년 9월 10일 월요일

AWS Redis와 Tomcat Session Clustering

근 두달만에 글을 쓰는것 같다 블로그에 글을 올리는게 쉽지 않다는 생각을 해본다.

오늘은 Redis를 이용하여 Tomcat Session Clustering하는 방법을 알아보고자한다.

앞에서 작성했던 AWS DynamoDB를 이용하여 Session Clustering은 Redis보다 속도가 느리다.
Elastic Cache인 memcache와 redis가 속도가 가장 빠르며 비싸다.



<AWS 발표자료중 한장>


Tomcat은 8버전을 기준으로 하며 Clustering에 필요한 라이브러리 및 설정은 https://github.com/ran-jit/tomcat-cluster-redis-session-manager를 참고 하였다.

우선 작업순서는 
1. AWS Redis를 생성
2. EC2 2대 생성(JAVA SDK8이 있는 환경)
3. Tomcat8.5를 설치
4. ALB에서 LB설정
5. https://github.com/ran-jit/tomcat-cluster-redis-session-manager 에 Download에서 latest version (2.0.4) 클릭하여 tomcat-cluster-redis-session-manager.zip 파일을 다운받는다.
6. 압축을 풀고 conf와 lib 폴더를 Tomcat 루트 폴더에 복사한다.(양쪽에 다 복사해야함)
7. github 에 나와있는데로 conf에 있는 파일들(redis-data-cache.properties, context.xml, web.xml)을 수정한다.

redis-data-cache.properties 아래 부분 수정
redis.hosts=<AWS Redis Endpoint>:<redis port>

context.xml 아래 태그 추가
<Valve className="tomcat.request.session.redis.SessionHandlerValve" />
<Manager className="tomcat.request.session.redis.SessionManager" />

web.xml 아래 태그 추가
<session-config>
<session-timeout>60</session-timeout>
</session-config>

8. tomcat webroot에 session id를 볼수 있는 jsp파일을 생성한다.
was1 jsp
<%
out.println("was1 sessionid : "+request.getRequestSessionId());
session.setAttribute("userid","honggildong");
out.println("tomcat set session userid :: "+session.getAttribute("userid"));
%>

was2 jsp
<%
out.println("was2 sessionid : "+request.getRequestSessionId());
out.println("tomcat set session userid :: "+session.getAttribute("userid"));
%>

9. tomcat을 was1번과 was2번으로 나누어 세션아이디가 동일한지 확인한다.













2018년 6월 25일 월요일

API Gateway Private 호출

API Gateway에서 VPCLink로 NLB를이용하여 VPC 안에있는 서버와 연결서비스를 한지 얼마안되어
6월에 드디어 VPC에 API Gateway호출을 위한 endpoint가 생겼다.

기존에는 S3, DynaoDB, EC2만 있었지만 Codebuild, EC2 Message, LoadBalancer, Api Gateway, KMS, Service Catalog, SNS, SSM이 생겼다.

간단하게 설정하는 방법은 아래와 같다.(API Gateway, VPC와 IAM에 대한 이해도가 있는사람 기준)

1. VPC에 Endpoint메뉴를 선택하여 Endpoint 생성버튼을 클릭.
2. AWS Service에 com.amazonaws.{region}.excute-api를 선택, 아래 VPC및 서브넷은 호출할 서버가 있는 서브넷으로 지정.
3. 보안그룹은 VPC IP range의 HTTPS inbound허용으로 새로 생성.
4. Endpoint가 생성완료되면 API의 Endpoint Type을 Private으로 변경.(Custom domain이 생성되어있으면 변경이 안됨. Custom domain제거후 변경)
5. 호출할 API Gateway를 선택하여 왼쪽메뉴의 Resource Policy를 선택하여 Policy를 생성.
(3가지 버튼으로 제공되며 Source VPC Whitelist를 선택하여 policy생성, Policy안 Condition에 {vpce}라고 되어있는부분에 생성한 Endpoint id로 대체하여야 함)
6. 저장하고 API를 Deploy진행
7. 경리된 server에서 API를 호출 테스트

참고 사이트는 아래와 같다.
https://aws.amazon.com/ko/blogs/compute/introducing-amazon-api-gateway-private-endpoints/

2018-9-12 추가 사항
1. PC Peering 으로 연결되었을때 VPC Endpoint를 이용하여 Private API를 호출하려면?
=> C5, i3.metal, R5, R5D, M5 및 Z1D 인스턴스 유형에만 호출된다.
https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/vpce-interface.html#vpce-interface-limitations

2. 혹시 DNS를 AWS에서 제공하는게 아닌 다른곳으로 설정되어있다면 API Gateway VPC endpoint에서 제공된 도메인으로 호출이 안된다. 이럴땐..
=> api 호출시 header 에 Host를 키로 하여 private api의 stg domain을 값으로 설정하여 호출해야 한다.(DX를 이용하는 경우에도 동일하게 해야함.)
https://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/apigateway-private-apis.html

2018년 6월 3일 일요일

AWS에서 Tomcat DynamoDB로 Session 동기화 하기


aws 에서 네트웍이 멀티 케스팅을 지원하지 않는다 하여 일반적인 톰켓에서 지원 하는 session clustering을 할수 없다고 한다. 그래서 redis나 memcache, dynamodb로 session clustring하는걸 지원한다고 한다.

redis,memcach, dynamodb중 dynamodb session clustering설정을 알아보고자 한다.


여기서는 톰캣 설치 및 다운로드는 제외한다.

clustering을 하려면 aws sdk 및 dynamodb session library를 다운받아 프로젝트나 tomcat lib파일에 위치 해야 한다.

아래는 다운로드 주소:
awssdk : https://sdk-for-java.amazonwebservices.com/latest/aws-java-sdk.zip
aws-dynamodb-session-tomcat : https://github.com/amazon-archives/aws-dynamodb-session-tomcat/releases/download/v2.0.4/aws-dynamodb-session-tomcat-2.0.4.jar(2018월1일기준)

완료 하였으면 tomcat에 conf에 있는 context.xml파일에 아래와 같이 추가 한다.
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <Manager className="com.amazonaws.services.dynamodb.sessionmanager.DynamoDBSessionManager"
             awsAccessKey="myAccessKey"
             awsSecretKey="mySecretKey"
             createIfNotExist="true" />
</Context>

위에  myAccessKey와 mySecretKey는 부여받은 키를 등록한다.

이러면 끝

앗 그런데 세션 정보를 보고 싶다. dynamodb 테이블을 보고 싶은데. 없다 어디에 있을까???
regionid를 설정하지 않아 기본적으로 us-east-1(Virginia)region DynamoDB에 가면 Tomcat_SessionState라는 테이블이 존재 한다.

어 그럼 내가 사용하는 region에 넣으려면 어떻게 해야 하나?
아래와 같이 regionid를 넣어주면 된다.

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <Manager className="com.amazonaws.services.dynamodb.sessionmanager.DynamoDBSessionManager"
             regionId="ap-northeast-2"
             endpoint="dynamodb.ap-northeast-2.amazonaws.com"
             createIfNotExist="true" />
</Context>

여기서 주의할점은 regionId와 endpoint를 꼭 같이 넣어줘야 한다.
하나만 있을경우에는 Session 동기화가 안된다.


앗 그런데 2번째에 accesskey와 securitykey넣는게 없다.
이럴때에는 EC2에 IAM role이 부여되었을경우 정상동작하며, role을 부여하지 않았을경우에는 accesskey와 securitykey를 넣어주자.


==2018-09-07 추가==
그런데도 세션동기화가 안되고 톰캣 로그에 session id를 못찾는다는 에러가 나온다면 dynamoDB에 쓰고 읽는 시간이 느려서 그렇다. ㅡ_ㅡ;;

DynamoDB session동기화는 autoscale 용으로 사용하기 보다는 LB의 Sticky를 이용하여 서버가 한쪽에 장애가 날때 세션이 끈기지 않도록 하는 기능으로 사용하는걸 추천한다.







2018년 3월 28일 수요일

AWS Cross Account IAM 설정

EC2에서 AWS다른 계정으로 권한을 할당 받아 실행할때는 아래와 같이 수행하면 된다.

1. AWS다른계정에 EC2가 있는 계정의 아이디를 이용하여 Policy를 만든다.
2. AWS다른계정에 Role을 만들어 Policy를 할당한다.(role의 ARN 저장)
3. IAM을 부여할 EC2가 있는 계정에 Role을 만든다.
role에 소스를 inline policy로 등록한다.
resource에는 다른계정에서 만든 role arn으로 수정한다.

{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::PRODUCTION-ACCOUNT-ID:role/UpdateApp" } }
4. ec2에 해당 role을 수행할때에는 sts를 받아 임시키를 받아 등록하여 수행하면 끝

sts 받는 방법
aws sts assume-role --role-arn {다른계정에 만든 role의 arn} --role-session-name {session이름(아무값이나 넣어도 되는듯)}

aws sts assume-role --role-arn "arn:aws:iam::999999999999:role/UpdateApp" --role-session-name "David-ProdUpdate"

하면 아래와 같이 출력되고
{ "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEeYjs1M2FUIgIJx9tQqNMBEXAMPLE CvSRyh0FW7jEXAMPLEW+vE/7s1HRpXviG7b+qYf4nD00EXAMPLEmj4wxS04L/uZEXAMPLECihzFB5lTYLto9dyBgSDy EXAMPLE9/g7QRUhZp4bqbEXAMPLENwGPyOj59pFA4lNKCIkVgkREXAMPLEjlzxQ7y52gekeVEXAMPLEDiB9ST3Uuysg sKdEXAMPLE1TVastU1A0SKFEXAMPLEiywCC/Cs8EXAMPLEpZgOs+6hz4AP4KEXAMPLERbASP+4eZScEXAMPLEsnf87e NhyDHq6ikBQ==", "Expiration": "2014-12-11T23:08:07Z", "AccessKeyId": "AKIAIOSFODNN7EXAMPLE" } }
아래와 같이 등록하면 해당 권한을 사용할수 있다.(window일 경우 export대신 set을 이용)
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY export AWS_SESSION_TOKEN=AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEeYjs1M2FUIgIJx9tQqNMBEXAMPLECvS Ryh0FW7jEXAMPLEW+vE/7s1HRpXviG7b+qYf4nD00EXAMPLEmj4wxS04L/uZEXAMPLECihzFB5lTYLto9dyBgSDyEXA MPLEKEY9/g7QRUhZp4bqbEXAMPLENwGPyOj59pFA4lNKCIkVgkREXAMPLEjlzxQ7y52gekeVEXAMPLEDiB9ST3UusKd EXAMPLE1TVastU1A0SKFEXAMPLEiywCC/Cs8EXAMPLEpZgOs+6hz4AP4KEXAMPLERbASP+4eZScEXAMPLENhykxiHen DHq6ikBQ==

참고 사이트
https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html

2018년 3월 26일 월요일

AWS VPC에 있는 서버에 접속을 하려면?


외부에서 AWS에 Virtual Private Network(VPC)에 있는 서버에 접속을 하려면 어떻게 해야 할까?

AWS에서는 Public영역에 Bastion Server을 이용하여 점프 할 수 있도록 구성하는것을 권장한다.

아래는 AWS에서 제공하는 Bastion의 Architecture 이다.

Bastion 서버에서 /var/log/bastion/bastion.log에 로그 파일이 있는데 접속된 명령들이 로그로 저장이 된다.이 로그 파일에는 날짜, SSH 클라이언트 연결 IP 주소, 사용자 이름, 작업 디렉터리 및 실행된 명령 등의 정보등이 기록된다.

이 로그에는 사용자 로그인 시 실행된 모든 명령에 대한 기록이 남아 있다. 

아래 그림에는 사용자가 특정 IP 주소를 통해 로그인했으며, 표준 사용자로 암호 파일을 제거하려고 시도한 후 루트 액세스로 에스컬레이션한 다음 접속 로그 제거를 시도했다고 기록된 로그를 보여준다.



bastion.log 파일에는 변경 불가능한 비트 세트가 있어 쉽게 제거하거나 조작할 수 없다고 한다. 악의적 사용자가 bastion.log 파일을 찾아낸 후 루트 권한을 얻어 보호를 해제하고 로그 파일을 삭제하더라도 로그의 사본이 포함된 섀도우 파일이 있다. 
섀도우 파일의 위치는 /var/log/bastion/.bastion.log이다.
이 섀도우 파일은 단순한 사본으로, 공격자가 찾아내 삭제할 수 있어 Cloud Watch Logs서비스를 이용하여 bastion.log파일을 저장하는걸 권장한다.

설치는 아마존에서 제공하는 quick start를 이용하여 배포할수 있다.

AWS설명서를 참고함.

또한 Amazon Linux에 github에 있는 shell을 생성하여 실행시키면 bastion.log가 생성된다.

bootstrap-bastion.sh

#!/bin/bash -x

yum -y update --security

##########################
## ENABLE SSH RECORDING ##
##########################

# Create a new folder for the log files
mkdir /var/log/bastion

# Allow ec2-user only to access this folder and its content
chown ec2-user:ec2-user /var/log/bastion
chmod -R 770 /var/log/bastion
setfacl -Rdm other:0 /var/log/bastion

# Make OpenSSH execute a custom script on logins
echo -e \"\\nForceCommand /usr/bin/bastion/shell\" >> /etc/ssh/sshd_config

# Block some SSH features that bastion host users could use to circumvent the solution
awk '!/AllowTcpForwarding/' /etc/ssh/sshd_config > temp && mv temp /etc/ssh/sshd_config
awk '!/X11Forwarding/' /etc/ssh/sshd_config > temp && mv temp /etc/ssh/sshd_config
echo \"AllowTcpForwarding no\" >> /etc/ssh/sshd_config
echo \"X11Forwarding no\" >> /etc/ssh/sshd_config

mkdir /usr/bin/bastion

cat > /usr/bin/bastion/shell << 'EOF'
# Check that the SSH client did not supply a command
if [[ -z $SSH_ORIGINAL_COMMAND ]]; then
  # The format of log files is /var/log/bastion/YYYY-MM-DD_HH-MM-SS_user
  LOG_FILE=\"`date --date=\"today\" \"+%Y-%m-%d_%H-%M-%S\"`_`whoami`\"
  LOG_DIR=\"/var/log/bastion/\"
  # Print a welcome message
  echo \"\"
  echo \"NOTE: This SSH session will be recorded\"
  echo \"AUDIT KEY: $LOG_FILE\"
  echo \"\"
  # I suffix the log file name with a random string. I explain why later on.
  SUFFIX=`mktemp -u _XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`
  # Wrap an interactive shell into \"script\" to record the SSH session
  script -qf --timing=$LOG_DIR$LOG_FILE$SUFFIX.time $LOG_DIR$LOG_FILE$SUFFIX.data --command=/bin/bash
else
  # The \"script\" program could be circumvented with some commands (e.g. bash, nc).
  # Therefore, I intentionally prevent users from supplying commands.
  echo \"This bastion supports interactive sessions only. Do not supply a command\"
  exit 1
fi
EOF
# Make the custom script executable
chmod a+x /usr/bin/bastion/shell
# Bastion host users could overwrite and tamper with an existing log file using \"script\" if
# they knew the exact file name. I take several measures to obfuscate the file name:
# 1. Add a random suffix to the log file name.
# 2. Prevent bastion host users from listing the folder containing log files. This is done
#    by changing the group owner of \"script\" and setting GID.
chown root:ec2-user /usr/bin/script
chmod g+s /usr/bin/script
# 3. Prevent bastion host users from viewing processes owned by other users, because the log
#    file name is one of the \"script\" execution parameters.
mount -o remount,rw,hidepid=2 /proc
awk '!/proc/' /etc/fstab > temp && mv temp /etc/fstab
echo \"proc /proc proc defaults,hidepid=2 0 0\" >> /etc/fstab
# Restart the SSH service to apply /etc/ssh/sshd_config modifications.
service sshd restart
############################
## EXPORT LOG FILES TO S3 ##
############################
cat > /usr/bin/bastion/sync_s3 << 'EOF'
# Copy log files to S3 with server-side encryption enabled.
# Then, if successful, delete log files that are older than a day.
LOG_DIR=\"/var/log/bastion/\"
aws s3 cp $LOG_DIR s3://${Bucket}/logs/ --sse --region ${AWS::Region} --recursive && find $LOG_DIR* -mtime +1 -exec rm {} \\;
EOF
chmod 700 /usr/bin/bastion/sync_s3
#######################################
## SYNCHRONIZE USERS AND PUBLIC KEYS ##
#######################################
# Bastion host users should log in to the bastion host with their personal SSH key pair.
# The public keys are stored on S3 with the following naming convention: \"username.pub\".
# This script retrieves the public keys, creates or deletes local user accounts as needed,
# and copies the public key to /home/username/.ssh/authorized_keys
cat > /usr/bin/bastion/sync_users << 'EOF'
# The file will log user changes
LOG_FILE=\"/var/log/bastion/users_changelog.txt\"
# The function returns the user name from the public key file name.
# Example: public-keys/sshuser.pub => sshuser
get_user_name () {
  echo \"$1\" | sed -e 's/.*\\///g' | sed -e 's/\\.pub//g'
}
# For each public key available in the S3 bucket
aws s3api list-objects --bucket ${Bucket} --prefix public-keys/ --region ${AWS::Region} --output text --query 'Contents[?Size>`0`].Key' | sed -e 'y/\\t/\\n/' > ~/keys_retrieved_from_s3
while read line; do
  USER_NAME=\"`get_user_name \"$line\"`\"
  # Make sure the user name is alphanumeric
  if [[ \"$USER_NAME\" =~ ^[a-z][-a-z0-9]*$ ]]; then
    # Create a user account if it does not already exist
    cut -d: -f1 /etc/passwd | grep -qx $USER_NAME
    if [ $? -eq 1 ]; then
      /usr/sbin/adduser $USER_NAME && \\
      mkdir -m 700 /home/$USER_NAME/.ssh && \\
      chown $USER_NAME:$USER_NAME /home/$USER_NAME/.ssh && \\
      echo \"$line\" >> ~/keys_installed && \\
      echo \"`date --date=\"today\" \"+%Y-%m-%d %H-%M-%S\"`: Creating user account for $USER_NAME ($line)\" >> $LOG_FILE
    fi
    # Copy the public key from S3, if an user account was created from this key
    if [ -f ~/keys_installed ]; then
      grep -qx \"$line\" ~/keys_installed
      if [ $? -eq 0 ]; then
        aws s3 cp s3://${Bucket}/$line /home/$USER_NAME/.ssh/authorized_keys --region ${AWS::Region}
        chmod 600 /home/$USER_NAME/.ssh/authorized_keys
        chown $USER_NAME:$USER_NAME /home/$USER_NAME/.ssh/authorized_keys
      fi
    fi
  fi
done < ~/keys_retrieved_from_s3
# Remove user accounts whose public key was deleted from S3
if [ -f ~/keys_installed ]; then
  sort -uo ~/keys_installed ~/keys_installed
  sort -uo ~/keys_retrieved_from_s3 ~/keys_retrieved_from_s3
  comm -13 ~/keys_retrieved_from_s3 ~/keys_installed | sed \"s/\\t//g\" > ~/keys_to_remove
  while read line; do
    USER_NAME=\"`get_user_name \"$line\"`\"
    echo \"`date --date=\"today\" \"+%Y-%m-%d %H-%M-%S\"`: Removing user account for $USER_NAME ($line)\" >> $LOG_FILE
    /usr/sbin/userdel -r -f $USER_NAME
  done < ~/keys_to_remove
  comm -3 ~/keys_installed ~/keys_to_remove | sed \"s/\\t//g\" > ~/tmp && mv ~/tmp ~/keys_installed
fi
EOF
chmod 700 /usr/bin/bastion/sync_users
###########################################
## SCHEDULE SCRIPTS AND SECURITY UPDATES ##
###########################################
cat > ~/mycron << EOF
*/5 * * * * /usr/bin/bastion/sync_s3
*/5 * * * * /usr/bin/bastion/sync_users
0 0 * * * yum -y update --security
EOF
crontab ~/mycron
rm ~/mycron
/opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --resource BastionHostInstance --region ${AWS::Region}

위 소스는 아래 github를 참고함.











2018년 3월 22일 목요일

lambda를 이용하여 모든 EC2의 volume을 주기적으로 snapshot으로 백업하기


각 계정에 EC2의 EBS를 백업하려 할때는 두가지방법이 있다. AMI를 이용하거나 EBS Volume을 snapshot으로 주기적으로 생성하는 방법 오늘은 그중에서 EBS volume을 lambda를 이용하여 백업하는 방법을 정리한다.

절차는 아래와 같다.
1. lambda를 생성하기 위한 role을 생성
2. lambda 생성 소스 추가 및 삭제 정책일 등록
3. cloud watch event추가 및 event 설정
4. 테스트
5. 완료


lambda source
#===================
import boto3
import datetime

import os

ec2 = boto3.resource('ec2')

def lambda_handler(event, context):
    print("\n\nAWS snapshot backups starting at %s" % datetime.datetime.now())
    instances = ec2.instances.filter(
        Filters=[{'Name': 'instance-state-name', 'Values': ['running']},{'Name': 'tag:BackupYN', 'Values': ['Y']}])
 
    for instance in instances:
        instance_name = filter(lambda tag: tag['Key'] == 'Name', instance.tags)[0]['Value']
        print("instance_name [%s]" % instance_name)
     
        for volume in ec2.volumes.filter(Filters=[{'Name': 'attachment.instance-id', 'Values': [instance.id]}]):
            description = 'scheduled-%s.%s-%s' % (instance_name, volume.volume_id,
                datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
         
            response = volume.create_snapshot(Description=description, VolumeId=volume.volume_id) 
         
            if response:
                print("Snapshot created with description [%s]" % description)
                ec2.create_tags( Resources=[response.snapshot_id],
                Tags=[
                    {'Key': 'Name', 'Value': description}
                ])
                #snapshot = ec2.Snapshot(response.snapshot_id)
                #snapshot.create_tags(Tags=[{'Key': 'Name','Value': description}])

        for snapshot in volume.snapshots.all():
            retention_days = int(os.environ['retention_days'])
            if snapshot.description.startswith('scheduled-') and ( datetime.datetime.now().replace(tzinfo=None) - snapshot.start_time.replace(tzinfo=None) ) > datetime.timedelta(days=retention_days):
                print("\t\tDeleting snapshot [%s - %s]" % ( snapshot.snapshot_id, snapshot.description ))
                snapshot.delete()

    print("\n\nAWS snapshot backups completed at %s" % datetime.datetime.now())
    return True
#==========

lambda를 이용하여 모든 EC2를 AMI Backup 하기

EC2의 AMI를 Lambda를 이용하여 Backup 하는 소스임.



import boto3
import datetime
import time
import os

ec2 = boto3.resource('ec2', region_name='ap-northeast-2')
ec = boto3.client('ec2')

def create_backup_snapshot():
    print("\n\nAWS snapshot backups starting at %s" % datetime.datetime.now())
    instances = ec2.instances.filter(
        Filters=[{'Name': 'instance-state-name', 'Values': ['running']},{'Name': 'tag:Name', 'Values': ['*DSTG*']},{'Name': 'tag:BackupYN', 'Values': ['Y']}])
     
    for instance in instances:
        instance_name = filter(lambda tag: tag['Key'] == 'Name', instance.tags)[0]['Value']
        print("instance_name [%s]" % instance_name)
     
        for volume in ec2.volumes.filter(Filters=[{'Name': 'attachment.instance-id', 'Values': [instance.id]}]):
            description = 'scheduled-%s.%s-%s' % (instance_name, volume.volume_id,
                datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
         
            response = volume.create_snapshot(Description=description, VolumeId=volume.volume_id) 
         
            if response:
                print("Snapshot created with description [%s]" % description)
                ec2.create_tags( Resources=[response.snapshot_id],
                Tags=[
                    {'Key': 'Name', 'Value': description}
                ])
                #snapshot = ec2.Snapshot(response.snapshot_id)
                #snapshot.create_tags(Tags=[{'Key': 'Name','Value': description}])

def backup_snapshot():
    print("\n\nAWS snapshot backups starting at %s" % datetime.datetime.now())
    instances = ec2.instances.filter(
        Filters=[{'Name': 'instance-state-name', 'Values': ['stopped']},{'Name': 'tag:Name', 'Values': ['*DSTG*']}])

    for instance in instances:
        instance_name = filter(lambda tag: tag['Key'] == 'Name', instance.tags)[0]['Value']
        print("instance_name [%s]" % instance_name)
        create_time = datetime.datetime.now()
        create_fmt = create_time.strftime('%Y-%m-%d')
        AMIid = ec.create_image(InstanceId=instance.id, Name="Lambda-" + instance_name +"-"+instance.id + " from " + create_fmt, Description="Lambda created AMI of instance " + instance.id + " from " + create_fmt, NoReboot=True, DryRun=False)

     

    print("\n\nAWS snapshot backups completed at %s" % datetime.datetime.now())


def lambda_handler(event, context):
    backup_snapshot()
    #create_backup_snapshot()
    return 'successful'

AWS Redis와 Tomcat Session Clustering

근 두달만에 글을 쓰는것 같다 블로그에 글을 올리는게 쉽지 않다는 생각을 해본다. 오늘은 Redis를 이용하여 Tomcat Session Clustering하는 방법을 알아보고자한다. 앞에서 작성했던 AWS DynamoDB를 이용하여 Sessi...