참고:
- 이 자습서에서는 Oracle Cloud에 액세스해야 합니다. 무료 계정에 등록하려면 Oracle Cloud Infrastructure Free Tier 시작하기를 참조하십시오.
- Oracle Cloud Infrastructure 인증서, 테넌시 및 구획에 대한 예제 값을 사용합니다. 실습을 완료하려면 이 값을 클라우드 환경에 해당하는 값으로 대체하십시오.
Terraform 및 cloud-init 스크립트를 사용하여 Oracle Cloud Infrastructure Compute 인스턴스에 예약된 IP 연결
소개
코드형 인프라(IaC) 세계에서 컴퓨팅 인스턴스의 프로비저닝 및 구성을 자동화하는 것은 효율적이고 확장 가능한 클라우드 배포에 필수적입니다. 예약된 IP 주소를 OCI(Oracle Cloud Infrastructure) 컴퓨트 인스턴스에 연결하면 Terraform 및 cloud-init가 강력한 조합을 제공합니다.
OCI 컴퓨트 Terraform 모듈에서는 인스턴스가 생성되는 동안 예약된 IP를 컴퓨트 인스턴스에 연결할 수 있는 옵션이 없습니다. 인스턴스 생성 후 예약된 IP만 연결할 수 있습니다. 이 블로그 게시물에서는 Terraform 및 클라우드 초기화 스크립트를 활용하여 예약된 IP를 OCI 컴퓨팅 인스턴스에 원활하게 연결하는 방법을 알아봅니다.
목표
Terraform 및 cloud-init 스크립트를 사용하여 예약된 IP를 OCI 컴퓨팅 인스턴스에 원활하게 연결합니다.
예약 IP란?
예약된 IP 주소는 가상 네트워크 내의 컴퓨트 인스턴스에 지정된 정적 IP입니다. 고정 IP가 필요한 애플리케이션을 일관되게 연결하고 네트워크 관리를 간소화합니다. 예약된 IP는 로드 균형 조정, 방화벽 규칙 및 보안 네트워크 통신과 같은 시나리오에서 일반적으로 사용됩니다.
필요 조건
먼저 OCI 환경에 액세스해야 합니다. 상시 무료 인스턴스를 손쉽게 생성할 수 있습니다. 이 인스턴스에는 많은 무료 용량과 US$300의 체험 크레딧이 제공됩니다.
환경이 있는 경우 사용자가 instance-family 리소스 및 storage-family를 관리할 수 있는 권한이 있는 그룹에 지정되었는지 확인합니다. 보안 모범 사례에서는 이미 권한이 지정된 콘솔 사용자를 사용하는 대신 사용자를 생성할 수 있습니다. 도움이 필요하면 문서를 체크 아웃하여 그룹을 생성하고 사용자에게 적절한 권한을 부여합니다.
- OCI 계정
- Terraform 액세스. 자세한 내용은 이 링크를 참조하십시오.
- 인스턴스가 실행될 공용 서브넷입니다. 인터넷 게이트웨이에 연결해야 합니다.
- 보조 VNIC가 만들어지고 예약된 IP가 지정된 전용 서브넷입니다. 서비스 게이트웨이에 연결해야 합니다.
- 그룹의 리소스에 네트워크 제품군 관리 권한이 필요한 동적 그룹입니다.
- 인스턴스 주체 인증에 대해 정책을 구성해야 합니다.
태스크 1: Terraform 스크립트 설정
여기서는 OCI Terraform 컴퓨트 인스턴스 생성 모듈에 cloud-init 스크립트를 메타데이터로 추가합니다. 또한 예약된 IP OCID 및 전용 서브넷 OCID를 무료 형식 태그로 컴퓨트 VM에 전달합니다.
resource "oci_core_public_ip" "pubip" {
# In case of Multiple Instances has to be created, Provide the count in the vars file.
# This block creates a Reserved Public IP from Oracle IP Pool
count = var.instance_count
compartment_id = var.compartment_id
display_name = var.res_ip_display_name
lifetime = "RESERVED"
private_ip_id = ""
}
resource "oci_core_instance" "pubiptest" {
count = var.instance_count
compartment_id = var.compartment_id
availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
display_name = var.display_name
shape = var.shape
# We will pass Reserved Public IP OCID and Private Subnet OCID as a freeform tags to the instance
freeform_tags = {
"publicIP" = resource.oci_core_public_ip.pubip[count.index].id
"SubnetId" = var.private_subnet_id
}
create_vnic_details {
display_name = var.vnic_display_name
assign_public_ip = true
subnet_id = var.public_subnet_id
}
source_details {
source_type = var.source_type
source_id = var.source_id
}
metadata = {
ssh_authorized_keys = var.pub_key
user_data = "${base64encode(file("./cloud-init.sh"))}"
}
}
위 스크립트는 예약된 IP(개수 변수 값을 고려)를 생성하고 임시 IP로 컴퓨트 인스턴스를 스핀업하여 기본 VNIC에 연결됩니다.
컴퓨트 메타데이터에서 cloud-init 스크립트를 전달합니다. 이 스크립트는 기존 임시 IP를 대체하여 예약 IP를 지정합니다.
작업 2: cloud-init 스크립트 이해
작업 2.1: OCI CLI 및 기타 필요한 툴 설치
다음 명령을 사용하여 OCI CLI 및 jq(JSON 구문 분석)를 설치합니다.
`sudo yum install -y python36-oci-cli jq`
작업 2.2: 인스턴스 메타데이터 검색
-
네트워킹, 볼륨 등에서 실행 중인 인스턴스에 대한 정보를 제공하는 인스턴스 메타데이터 서비스를 사용합니다. Freeform 태그 값도 포함된 인스턴스 메타데이터 서비스를 사용하여 인스턴스 OCID, 구획 ID, subnetID(Freeform 태그로 전달된 전용 서브넷 OCID) 및 publicIP(Freeform 태그로 전달된 예약된 IPOCID)를 검색합니다.
metadata=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v2/instance) instanceid=$(echo $metadata | jq -r '.id') compartmentid=$(echo $metadata | jq -r '.compartmentId') subnetid=$(echo $metadata | jq -r '.freeformTags.SubnetId') publicIp=$(echo $metadata | jq -r '.freeformTags.publicIP') -
oci-cli를 사용하여 기본 VNIC OCID, 전용 IP ID(기본 VNIC에 지정된 전용 IP의 OCID), 임시 공용 IP 및 임시 공용 IP OCID를 검색합니다.primaryvnicid=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v1/vnics/ | jq -r '.[].vnicId') privateIpId=$(oci network private-ip list --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data[].id') ephpublicIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') ephpublicIpId=$( oci network public-ip get --auth instance_principal --public-ip-address $ephpublicIp | jq -r '.data.id')
작업 2.3: 보조 VNIC 연결
다음 명령을 실행하여 전용 서브넷을 사용할 컴퓨트 VM에 보조 VNIC를 연결합니다.
oci compute instance attach-vnic --instance-id $instanceid --subnet-id $subnetid --auth instance_principal --wait
작업 2.4: 경로 구성
-
보조 VNIC가 만들어지고 VM에 연결되면 보조 VNIC를 구성하고 경로에 추가합니다. 경로를 구성하려면 Oracle에서 제공한 스크립트를 사용합니다.
wget https://docs.oracle.com/en-us/iaas/Content/Resources/Assets/secondary_vnic_all_configure.sh sudo chmod u+x ./secondary_vnic_all_configure.sh sudo ./secondary_vnic_all_configure.sh -c -
구성이 완료되면 새 경로가 VM 경로에 추가됩니다.
sudo route -n명령을 사용하여 동일한 항목을 확인할 수 있습니다.
작업 2.5: 보조 VNIC 경로를 기본 경로로 설정
-
IDMS를 사용하여 보조 VNIC에 대한 게이트웨이 IP를 가져옵니다. 인스턴스 경로 테이블에 추가됩니다.
gatewayIP=$(curl http://169.254.169.254/opc/v1/vnics/ | jq -c '.[] | ( select(.vnicId=="'$secondaryvnicid'" ))' | jq -r '.virtualRouterIp') -
아래 명령을 사용하여 기본 네트워크 인터페이스를 가져옵니다.
iname=$(sudo ./secondary_vnic_all_configure.sh | awk '{print $8}' | awk 'END{print}') -
아래 명령을 실행하여 기본 경로를 보조 VNIC로 추가합니다.
sudo route add default gw $gatewayIP dev $iname -
sudo route -n명령을 사용하여 다시 확인합니다.
작업 2.6: 임시 공용 IP 삭제
-
VM에 연결된 임시 공용 IP를 삭제합니다. 보조 VNIC를 기본 경로로 지정했고 보조 VNIC가 있는 서브넷이 있으므로 서비스 게이트웨이가 연결되어 다른 OCI 서비스(이 경우 VCN)와 통신할 수 있습니다.
delpubIp=$(oci network public-ip delete --force --auth instance_principal --public-ip-id $ephpublicIpId --wait-for-state TERMINATED) -
다음 명령을 사용하여 임시 IP가 성공적으로 삭제되었는지 확인합니다.
checkIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"')
작업 2.7: 예약된 IP 연결
자유 형식 태그에서 공용 IP OCID가 있으며 임시 IP가 삭제되었으므로 예약된 IP를 기본 VNIC에 연결할 수 있습니다. 아래 명령은 예약된 IP를 인스턴스의 기본 VNIC에 연결합니다.
assign=$(oci network public-ip update --force --auth instance_principal --public-ip-id $publicIp --private-ip-id $privateIpId --wait-for-state ASSIGNED)
작업 2.8: 보조 VNIC 분리
-
기본 VNIC에 Reserved Public이 연결되었으므로 이제 보조 VNIC를 분리하는 것이 좋습니다. 아래 명령을 사용하여 보조 VNIC를 분리하고 이에 따라 경로 규칙을 업데이트합니다.
detach=$(oci compute instance detach-vnic --compartment-id $compartmentid --vnic-id $secondaryvnicid --force --auth instance_principal) sudo ./secondary_vnic_all_configure.sh -d -
다음 스크립트는 모든 단계를 함께 표시합니다. 이 스크립트는 실패 시 최대 3번 재시도했으며 OCI 이벤트 서비스를 사용하여 실패 시 통지를 설정할 수 있습니다.
#!/bin/bash # coding: utf-8 sudo yum install -y python36-oci-cli function getdetails() { # Fetch data using instance principal authentication metadata=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v2/instance) instanceid=$(echo $metadata | jq -r '.id') compartmentid=$(echo $metadata | jq -r '.compartmentId') subnetid=$(echo $metadata | jq -r '.freeformTags.SubnetId') publicIp=$(echo $metadata | jq -r '.freeformTags.publicIP') primaryvnicid=$(curl -H 'Authorization: Bearer Oracle' http://169.254.169.254/opc/v1/vnics/ | jq -r '.[].vnicId') privateIpId=$(oci network private-ip list --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data[].id') ephpublicIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') ephpublicIpId=$( oci network public-ip get --auth instance_principal --public-ip-address $ephpublicIp | jq -r '.data.id') if [[ -z "$subnetid" || "$subnetid" == "" || ${#subnetid} == 0 || -z "$publicIp" || ${#publicIp} == 0 || -z "$instanceid" || -z "$compartmentid" || -z "$publicIpData" || -z "$privateIpId" || -z "$primaryvnicid" || -z "$ephpublicIp" || -z "$ephpublicIpId" ]]; then echo "Missing some details, retrying..." return 1 fi return 0 } # Retry the `getdetails` function thrice attachVNIC() { attachvnic=$(oci compute instance attach-vnic --instance-id $instanceid --subnet-id $subnetid --auth instance_principal --wait) } for i in {1..3}; do getdetails if [[ $? -eq 0 ]]; then attachVNIC if [[ -n "$attachvnic" ]]; then secondaryvnicid=$(echo $attachvnic | jq -r '.data.id') echo $secondaryvnicid check2VNICs=$(oci compute instance list-vnics --instance-id $instanceid --auth instance_principal | jq -r '.data[].id') echo $check2VNICs gatewayIP=$(curl http://169.254.169.254/opc/v1/vnics/ | jq -c '.[] | ( select(.vnicId=="'$secondaryvnicid'" ))' | jq -r '.virtualRouterIp') if [[ (-n "$gatewayIP") ]]; then echo $gatewayIP wget https://docs.oracle.com/en-us/iaas/Content/Resources/Assets/secondary_vnic_all_configure.sh sudo chmod u+x ./secondary_vnic_all_configure.sh sudo ./secondary_vnic_all_configure.sh -c iname=$(sudo ./secondary_vnic_all_configure.sh | awk '{print $8}' | awk 'END{print}') echo $iname sudo route add default gw $gatewayIP dev $iname route oci os ns get --auth instance_principal delpubIp=$(oci network public-ip delete --force --auth instance_principal --public-ip-id $ephpublicIpId --wait-for-state TERMINATED) checkIp=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') if [[ -z "$checkIp" || "$checkIp" == "null" ]]; then echo "Assigning Reserved IP" assign=$(oci network public-ip update --force --auth instance_principal --public-ip-id $publicIp --private-ip-id $privateIpId --wait-for-state ASSIGNED) detach=$(oci compute instance detach-vnic --compartment-id $compartmentid --vnic-id $secondaryvnicid --force --auth instance_principal) sudo ./secondary_vnic_all_configure.sh -d checkIp2=$(oci network vnic get --vnic-id $primaryvnicid --auth instance_principal | jq -r '.data."public-ip"') echo "Reserved IP $checkIp2" if [[ -z "$checkIp2" ]]; then oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Reserved IP Not Assigned","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit; fi else oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Ephemeral IP Not Deleted","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit; fi break; else oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Gateway IP not fetched","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit; fi else break; fi fi done if [[ -z "$attachvnic" ]]; then echo "Failed" oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Secondary VNIC not attached","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit fi checkVNICs2=$(oci compute instance list-vnics --instance-id $instanceid --auth instance_principal | jq -r '.data | length') if [[ "$checkVNICs2" > 1 ]]; then echo "Detaching Secondary VNIC Failed" oci compute instance update --instance-id $instanceid --freeform-tags '{"errorStatus":"Detaching Secondary VNIC Failed","SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal exit fi oci compute instance update --instance-id $instanceid --freeform-tags '{"SubnetId":"'$subnetid'","publicIP":"'$publicIp'"}' --force --auth instance_principal
다음 단계
이는 샘플 구현이며 이를 cloud-init 스크립트로 사용하기 전에 해당 변경을 수행합니다. 이 테스트는 Oracle Linux 8에서 테스트되었습니다.
다른 Linux Flavor를 선택할 경우 oci-cli 설치 절차가 변경됩니다. 자세한 내용은 Installing the CLI를 참조하십시오.
관련 링크
승인
작성자 - Rithesh Subramanian(OCI Cloud Architect)
추가 학습 자원
docs.oracle.com/learn에서 다른 실습을 탐색하거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스할 수 있습니다. 또한 education.oracle.com/learning-explorer을 방문하여 Oracle Learning Explorer가 됩니다.
제품 설명서는 Oracle Help Center를 참조하십시오.
Attach a Reserved IP to an Oracle Cloud Infrastructure Compute Instance using Terraform and cloud-init Script
F82850-01
June 2023
Copyright © 2023, Oracle and/or its affiliates.