AWS:Lambda — EC2 레이블을 EBS 섹션 1로 복사 — 파이썬 및 boto3

AWS:Lambda — EC2 레이블을 EBS 섹션 1로 복사 — 파이썬 및 boto3



우리는 WorkerNode 그룹이 몇 개 있는 AWS Elastic Kubernetes 서비스 그룹을 가지고 있습니다. 이 그룹들은 eksctl을 사용하여 AWS 자동 축소 그룹으로 만든 것입니다. 더 자세한 정보는 AWS Elastic Kubernetes Service: a cluster creation automation, part 2 – Ansible, eksctl을 참고하십시오.eksctl의 WorkerNode 그룹 구성에는 AWS 인벤토리를 위한 태그 세트가 있습니다.
--------
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: "{{ eks_cluster_name }}"
  region: "{{ region }}"
  version: "{{ k8s_version }}"

nodeGroups:

### Common ###

  - name: "{{ k8s_common_nodegroup_name }}-{{ item }}-v2021-09"
    instanceType: "{{ k8s_common_nodegroup_instance_type }}"
    privateNetworking: true
    labels:
      role: common-workers
    ...
    tags:
      Tier: "Devops"
      Domain: "eks.devops.{{ region }}.{{ env | lower }}.bttrm.local"
      ServiceType: "EC2"
      Env: {{ env }}
      Function: "Kubernetes WorkerNode"
      NetworkType: "Private"
      DataClass: "Public"
      AssetOwner: "{{ asset_owner }}"
      AssetCustodian: "{{ asset_custodian }}"
      OperatingSystem: "Amazon Linux"
      JiraTicket: "{{ jira_ticket }}"
      ConfidentialityRequirement: "Med"
      IntegrityRequirement: "Med"
      AvailabilityRequirement: "Med"
...
이러한 태그는 자동 배율 조정 그룹에 적용됩니다.

그런 다음 자동 배율 조정 그룹에서 생성된 EC2 인스턴스에 적용됩니다.
문제는 이 라벨들이 EC2에 연결된 탄성 블록 저장 장치에 복사되지 않았다는 것이다.
또한 Kubernetes Worker Nodes를 제외하고, AWS 계정에서 흔히 볼 수 있는 EC2 사례가 있습니다. 그 중 일부는 루트 장치만 있고, 다른 일부는 데이터 백업에 추가 디스크를 사용할 수 있습니다.
또한 EC2에서 레이블을 복제할 뿐만 아니라 디스크의 기능을 설명하는 전용 레이블을 추가해야 합니다. — 루트 볼륨, 데이터 볼륨 및 Kubernetes PVC 볼륨
우리 어떻게 해요?AWS의 거의 모든 것들처럼 AWS 콘솔은 이런 내용을 포함하지 않는다 — AWS Lambda 서비스를 사용하여 새 EC2를 시작할 때 트리거하는 함수를 만들고 이 EC2의 태그를 이 인스턴스에 연결된 모든 EBS 볼륨에 복사합니다.
그렇다면 AWS Lambda 함수의 논리에서 다음을 찾아야 합니다.
새 EC2 생성 시
  •  — Lambda 함수
  • 트리거
  • 이 함수는 EC2 ID를 사용하고 관련된 모든 EBS 볼륨
  • 을 찾습니다.
  • AWS 태그를 EC2에서 모든 EBS
  • 으로 복사
  • 에 Role:
  • 이라는 새로운 태그 추가
  • 만약 EBS가 Kubernetes PVC에서 만들어졌고 Kubernetes Worker Node AWS AutoScale 그룹에서 시작된 EC2에 설치되었다면, 탭 Role: "PvcVolume"을 설정할 것입니다
  • EBS가 일반 EC2 작성 중에 생성된 경우 해당 마운트 지점을 확인하고 사용할 값을 결정합니다.  -  Role: "RootVolume" 또는 Role: "DataVolume"
  • 가자.

    컨텐트

  • Python script: copy AWS Tags
  • boto3: getting a list of EC2 instances and their EBS volumes
  • boto3: adding AWS Tags to an EBS
  • boto3: copy AWS Tags from an EC2 to its EBS
  • Python 스크립트:AWS 태그 복사


    우선, 파이톤 스크립트를 작성해서 테스트를 하고, 본문의 두 번째 부분에서 AWS Lambda로 넘어가자.
    Lambda 함수에 맞게 빠른 업데이트를 수행하여 전용 EC2 ID를 사용할 수 있도록 합니다.

    boto3: EC2 인스턴스 및 EBS 볼륨 목록 가져오기


    첫 번째는 AWS 계정에서 인증을 하고 특정 영역에 있는 모든 EC2 인스턴스를 검색한 다음 각 EC2에 연결된 EBS 볼륨의 목록을 검색하는 것입니다.
    그리고 이런 정보가 있으면 우리는 그들의 꼬리표를 가지고 놀 수 있다.
    시나리오:
    #!/usr/bin/env python
    
    import os   
    import boto3
    
    ec2 = boto3.resource('ec2',
            region_name=os.getenv("AWS_DEFAULT_REGION"),
            aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
            aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY")
        )
    
    def lambda_handler(event, context):
    
        base = ec2.instances.all()
    
        for instance in base:
    
            print("\n[DEBUG] EC2\n\t\tID: " + str(instance))
            print("\tEBS")
    
            for vol in instance.volumes.all():
    
                vol_id = str(vol)
                print("\t\tID: " + vol_id)
    
    if __name__ == " __main__":
        lambda_handler(0, 0)
    
    여기, ec2 변수 중,ec2 유형의 boto3.resource 대상을 만들고 있으며, $AWS_ACCESS_KEY_ID$AWS_SECRET_ACCESS_KEY 변수를 사용하여AWS 계정에서 신분 검증을 진행할 것입니다.잠시 후 Lambda에서는 IAWS IAM 역할을 통해 인증 및 승인이 완료됩니다.
    스크립트 끝에 lambda_handler() 함수를 호출했습니다. 만약 스크립트가 전용 프로그램으로 실행된다면 Python: what is the if name == “main” ?을 참고하여 자세한 정보를 얻으십시오.lambda_handler()에서 우리는 ec2.instances.all() 방법을 사용하여 한 구역의 모든 실례를 가져오고 for 순환에서 instance.volumes.all() 을 호출하여 이 EC2에 연결된 EBS 볼륨의 목록을 가져옵니다.
    현재 lambda_handler()의 매개 변수는'0, 0'으로 전달되고 있으며, 잠시 후 Lambda에서 이벤트와 상하문 대상을 배치할 것입니다.
    AWS 인증 변수를 설정하려면:
    $ export AWS_ACCESS_KEY_ID=AKI***D4Q
    $ export AWS_SECRET_ACCESS_KEY=QUC***BTI
    $ export AWS_DEFAULT_REGION=eu-west-3
    
    스크립트를 실행하려면 다음과 같이 하십시오.
    $ ./ec2_tags.py
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-0df2fe9ec4b5e1855')
    EBS
    ID: ec2.Volume(id=’vol-0d11fd27f3702a0fc’)
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-023529a843d02f680')
    EBS
    ID: ec2.Volume(id=’vol-0f3548ae321cd040c’)
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-02ab1438a79a3e475')
    EBS
    ID: ec2.Volume(id=’vol-09b6f60396e56c363')
    ID: ec2.Volume(id=’vol-0d75c44a594e312a1')
    …
    
    좋아, 그것이 작용했어!우리는 eu-west-3 AWS 지역에 모든 CCCC2를 보유하고 있으며, 각 EC2에는 EBS 목록이 첨부되어 있다.
    다음은요?다음 단계에서는 EC2에 볼륨을 불러오는 방법을 확인하고 그 마운트 지점을 알 것입니다. 이 디스크가 루트인지 데이터의 다른 볼륨인지 알 수 있습니다.
    이것은 attachments() 속성을 획득하여 실현할 수 있으며, 이 속성은 Device 키로 값을 보존합니다.
    스크립트에 device_id이라는 새 변수를 설정합니다.
    ...
            for vol in instance.volumes.all():
    
                vol_id = str(vol)
                device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"
    
                print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id + "\n")
    ...
    
    스크립트를 다시 실행하려면:
    $ ./ec2_tags.py
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-0df2fe9ec4b5e1855')
    EBS
    ID: ec2.Volume(id=’vol-0d11fd27f3702a0fc’)
    Dev: ec2.vol.Device(‘/dev/xvda’)
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-023529a843d02f680')
    EBS
    ID: ec2.Volume(id=’vol-0f3548ae321cd040c’)
    Dev: ec2.vol.Device(‘/dev/xvda’)
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-02ab1438a79a3e475')
    EBS
    ID: ec2.Volume(id=’vol-09b6f60396e56c363')
    Dev: ec2.vol.Device(‘/dev/xvda’)
    ID: ec2.Volume(id=’vol-0d75c44a594e312a1')
    Dev: ec2.vol.Device(‘/dev/xvdbm’)
    …
    
    여기에 i-02ab1438a79a3e475라는 아이디가 있는데 이 EC2는 EBS 볼륨 두 개를 설치했습니다. — vol-09b6f60396e56c363as/dev/xvda과vol-0d75c44a594e312a1as/dev/xvdbm./dev/xvda은 분명히 뿌리 부피이고 /dev/xvdbm - 일부 추가 데이터입니다.

    boto3: EBS에 AWS 태그 추가


    이제 역할 태그를 작성하여 역할이 다음 값과 일치하도록 합니다.
  • EBS에 kubernetes.io/created-for/pvc/name 키 레이블이 있는 경우 Role: "PvcVolume"
  • PVC 볼륨이 아닌 경우 마운트 지점을 확인하고, 장치 = "/dev/xvda"인 경우 Role: "RootVolume"을 설정합니다.
  • 마지막으로 장치 변수에 다른 값이 있는 경우 Role: "DataDisk"으로 EBS를 표시하면 됩니다.
    이를 위해 태그 설정에 사용할 다른 함수와 is_pvc()이라는 작은 함수를 추가합니다. 이 함수는 EBS에 kubernetes.io/created-for/pvc/name 태그가 있는지 확인합니다.
    ...
    def is_pvc(vol):
    
        try:
            for tag in vol.tags:
                if tag['Key'] == 'kubernetes.io/created-for/pvc/name':
                    return True
                    break
        except TypeError:
                return False
    
    def set_role_tag(vol):
    
        device = vol.attachments[0]['Device']
        tags_list = []
        values = {}
    
        if is_pvc(vol):
            values['Key'] = "Role"
            values['Value'] = "PvcDisk"
            tags_list.append(values)
        elif device == "/dev/xvda":
            values['Key'] = "Role"
            values['Value'] = "RootDisk"
            tags_list.append(values)
        else:
            values['Key'] = "Role"
            values['Value'] = "DataDisk"
            tags_list.append(values)
    
        return tags_list
    ...
    
    여기에서 set_role_tag() 함수에서 우리는vol의 값을 매개 변수로 is_pvc() 함수에 전달하고 이 함수는'kubernetes'의 표시를 검사한다.io/는/pvc/name'키로 생성됩니다.이 try/except은 EBS에 레이블이 있는지 확인하는 데 사용됩니다.
    쿠베르네트 가문이라면io/created for/pvc/name'태그가 발견되면 is_pvc()은True를 반환하고 그렇지 않으면 False를 반환합니다.
    그리고 if/elif/else 조건에서 우리는 EBS가 PVC 볼륨인지 확인하고, 만약 그렇다면 Role: "PvcVolume"으로 표시하고, 그렇지 않으면 불러오는 지점을 검사하며, '/dev/xvda' 로 불러오면 Role: "RootVolume"을, 로 설정하면 Role: "DataDisk"을 사용합니다.set_role_tag() 호출을 lambda_handler()vol.create_tags() 함수의 매개 변수로 추가합니다.
    ...
    def lambda_handler(event, context):
    
        base = ec2.instances.all()
    
        for instance in base:
    
            print("\n[DEBUG] EC2\n\t\tID: " + str(instance))
            print("\tEBS")
    
            for vol in instance.volumes.all():
    
                vol_id = str(vol)
                device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"
                print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id)
    
                role_tag = vol.create_tags(Tags=set_role_tag(vol))
                print("\t\tTags set:\n\t\t\t" + str(role_tag))
    ...
    
    스크립트를 다시 실행하려면:
    $ ./ec2_tags.py
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-0df2fe9ec4b5e1855')
    EBS
    ID: ec2.Volume(id=’vol-0d11fd27f3702a0fc’)
    Dev: ec2.vol.Device(‘/dev/xvda’)
    Tags set:
    [ec2.Tag(resource_id=’vol-0d11fd27f3702a0fc’, key=’Role’, value=’RootDisk’)]
    …
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-02ab1438a79a3e475')
    EBS
    ID: ec2.Volume(id=’vol-09b6f60396e56c363')
    Dev: ec2.vol.Device(‘/dev/xvda’)
    Tags set:
    [ec2.Tag(resource_id=’vol-09b6f60396e56c363', key=’Role’, value=’RootDisk’)]
    ID: ec2.Volume(id=’vol-0d75c44a594e312a1')
    Dev: ec2.vol.Device(‘/dev/xvdbm’)
    Tags set:
    [ec2.Tag(resource_id=’vol-0d75c44a594e312a1', key=’Role’, value=’PvcDisk’)]
    
    i-02ab1438a79a3e47 EC2 인스턴스의 볼륨을 검토합니다.
    루트 볼륨vol-09b6f60396e56c363:

    그리고 Kubernetes PVC - 0d75c44a594e312a1권:

    좋습니다. 캐릭터 태그 생성을 추가했습니다. 이제 EC2에서 EBS로 AWS 태그를 복사하는 기능을 추가해야 합니다.

    boto3: EC2에서 EBS로 AWS 태그 복사


    또한 태그 복사본을 전용 함수로 이동할 수 있습니다. 이름하여 copy_ec2_tags()으로 지정하면 매개변수가 적용되고 EC2 ID가 전달됩니다.
    ...
    def copy_ec2_tags(instance):
    
        tags_list = []
        values = {} 
    
        for instance_tag in instance.tags:
    
            if instance_tag['Key'] == 'Env':
                tags_list.append(instance_tag)
            elif instance_tag['Key'] == 'Tier':
                tags_list.append(instance_tag)
            elif instance_tag['Key'] == 'DataClass':
                tags_list.append(instance_tag)
    
        return tags_list
    ...
    
    함수 중, 하나의 순환에서, 우리는 실례의 모든 표기를 검사합니다. 함수에 지정된 세 개의 표기 중 하나를 찾으면, 그것들은 목록 tags_list[]에 추가되고, 잠시 후에 vol.create_tags()에 전달됩니다.copy_ec2_tags() 실행을 lambda_handler()에 추가합니다.
    ...
    def lambda_handler(event, context):
    
        base = ec2.instances.all()
    
        for instance in base:
    
            print("\n[DEBUG] EC2\n\t\tID: " + str(instance))
            print("\tEBS")
    
            for vol in instance.volumes.all():
    
                vol_id = str(vol)
                device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"
                print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id)
    
                role_tag = vol.create_tags(Tags=set_role_tag(vol))
                ec2_tags = vol.create_tags(Tags=copy_ec2_tags(instance))
                print("\t\tTags set:\n\t\t\t" + str(role_tag) + "\n\t\t\t" + str(ec2_tags))
    ...
    
    실행:
    $ ./ec2_tags.py
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-0df2fe9ec4b5e1855')
    EBS
    ID: ec2.Volume(id=’vol-0d11fd27f3702a0fc’)
    Dev: ec2.vol.Device(‘/dev/xvda’)
    Tags set:
    [ec2.Tag(resource_id=’vol-0d11fd27f3702a0fc’, key=’Role’, value=’RootDisk’)]
    [ec2.Tag(resource_id=’vol-0d11fd27f3702a0fc’, key=’DataClass’, value=’Public’), ec2.Tag(resource_id=’vol-0d11fd27f3702a0fc’, key=’Env’, value=’Dev’), ec2.Tag(resource_id=’vol-0d11fd27f3702a0fc’, key=’Tier’, value=’Devops’)]
    …
    [DEBUG] EC2
    ID: ec2.Instance(id=’i-02ab1438a79a3e475')
    EBS
    ID: ec2.Volume(id=’vol-09b6f60396e56c363')
    Dev: ec2.vol.Device(‘/dev/xvda’)
    Tags set:
    [ec2.Tag(resource_id=’vol-09b6f60396e56c363', key=’Role’, value=’RootDisk’)]
    [ec2.Tag(resource_id=’vol-09b6f60396e56c363', key=’Env’, value=’Dev’), ec2.Tag(resource_id=’vol-09b6f60396e56c363', key=’DataClass’, value=’Public’), ec2.Tag(resource_id=’vol-09b6f60396e56c363', key=’Tier’, value=’Devops’)]
    ID: ec2.Volume(id=’vol-0d75c44a594e312a1')
    Dev: ec2.vol.Device(‘/dev/xvdbm’)
    Tags set:
    [ec2.Tag(resource_id=’vol-0d75c44a594e312a1', key=’Role’, value=’PvcDisk’)]
    [ec2.Tag(resource_id=’vol-0d75c44a594e312a1', key=’Env’, value=’Dev’), ec2.Tag(resource_id=’vol-0d75c44a594e312a1', key=’DataClass’, value=’Public’), ec2.Tag(resource_id=’vol-0d75c44a594e312a1', key=’Tier’, value=’Devops’)]
    ...
    
    및 다음을 확인합니다.

    이제 전체 스크립트가 다음과 같이 표시됩니다.
    #!/usr/bin/env python
    
    import os
    import boto3
    
    ec2 = boto3.resource('ec2',
            region_name=os.getenv("AWS_DEFAULT_REGION"),
            aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
            aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY")
        )
    
    def lambda_handler(event, context):
    
        base = ec2.instances.all()
    
        for instance in base:
    
            print("[DEBUG] EC2\n\t\tID: " + str(instance))
            print("\tEBS")
    
            for vol in instance.volumes.all():
    
                vol_id = str(vol)
                device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"
                print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id)
    
                role_tag = vol.create_tags(Tags=set_role_tag(vol))
                ec2_tags = vol.create_tags(Tags=copy_ec2_tags(instance))
                print("\t\tTags set:\n\t\t\t" + str(role_tag) + "\n\t\t\t" + str(ec2_tags) + "\n")
    
    def is_pvc(vol): 
    
        try:
            for tag in vol.tags:
                if tag['Key'] == 'kubernetes.io/created-for/pvc/name':
                    return True
                    break
        except TypeError:
                return False
    
    def set_role_tag(vol):
    
        device = vol.attachments[0]['Device']
        tags_list = []
        values = {}
    
        if is_pvc(vol):
            values['Key'] = "Role"
            values['Value'] = "PvcDisk"
            tags_list.append(values)
        elif device == "/dev/xvda":
            values['Key'] = "Role"
            values['Value'] = "RootDisk"
            tags_list.append(values)
        else:   
            values['Key'] = "Role"
            values['Value'] = "DataDisk"
            tags_list.append(values)
    
        return tags_list
    
    def copy_ec2_tags(instance):
    
        tags_list = []
        values = {} 
    
        for instance_tag in instance.tags:
    
            if instance_tag['Key'] == 'Env':
                tags_list.append(instance_tag)
            elif instance_tag['Key'] == 'Tier':
                tags_list.append(instance_tag)
            elif instance_tag['Key'] == 'DataClass':
                tags_list.append(instance_tag)
            elif instance_tag['Key'] == 'JiraTicket':
                tags_list.append(instance_tag)
    
        return tags_list
    
    if __name__ == " __main__":
        lambda_handler(0, 0)
    
    이제 AWS Lambda 함수를 계속 사용할 수 있도록 완료했습니다.AWS: Lambda — copy EC2 tags to its EBS, part 2 — create a Lambda function 게시물의 다음 부분을 참조하십시오.
    최초로 RTFM: Linux, DevOps, and system administration에 발표되었다.

    좋은 웹페이지 즐겨찾기