aws ec2 and security group copy to other region

 

剛好最近有用到

順手作了簡單的網頁版本,可以線上修改內容

按下Done之後…

底部還是跑bash...

#!/bin/bash
#####################################
#For test auto dr site to new region#
#Createby Sam.            2017/12/21#
#####################################
LOCATION=/tmp
SAMLOG=/var/www/html/$$samlog
SAMSG=/$LOCATION/$$samsg
SAMVPC=/$LOCATION/$$samvpc
SAMSOURCEINFO=/$LOCATION/$$samsourceinfo
SAMSGINFO=/$LOCATION/$$samsginfo
SAMSGNEWINFO=/$LOCATION/$$samsgnewinfo
SAMSOURCESGNAME=/$LOCATION/$$samsourcename
SAMNEWSGNAME=/$LOCATION/$$samnewsgname
SAMGROUPINFO=/$LOCATION/$$samgroupinfo
SAMROOTDEVICENAME=/$LOCATION/$$samrootdevicename
SAMIMAGEID=/$LOCATION/$$samimageid
SAMIMAGEIDNEW=/$LOCATION/$$samimageidnew
SAMNEWINSTANCEINFO=/$LOCATION/$$samnewinstanceinfo
SAMNEWSUBID=/$LOCATION/$$samnewsubid
SAMNEWVPCID=/$LOCATION/$$samnewvpcid
SAMSUMSGNAME=/$LOCATION/$$samsumsgname
SAMCUSTOM=/var/www/html/b
export AWS_ACCESS_KEY_ID=`cat $SAMCUSTOM |grep aws_access_key_id |awk -F\= '{print $2}'`
export AWS_SECRET_ACCESS_KEY=`cat $SAMCUSTOM |grep aws_secret_access_key |awk -F\= '{print $2}'`
SAMTIME(){
	NOW_TIME=`date "+%Y-%m-%d %H:%M:%S"`
	}
SAMTIME
STARTTIME=$NOW_TIME
START_TIME=$SECONDS
echo "Start $NOW_TIME" > $SAMLOG
SOURCEREGION=`cat $SAMCUSTOM |grep SOURCEREGION |grep = | awk -F "=" '{print $2}'`
NEWREGION=`cat $SAMCUSTOM |grep NEWREGION |grep = | awk -F "=" '{print $2}'`
SOURCEINSTANCESID=`cat $SAMCUSTOM |grep SOURCEINSTANCESID |grep = | awk -F "=" '{print $2}'`
DESTIP=`cat $SAMCUSTOM |grep DESTIP |grep = | awk -F "=" '{print $2}'`
DESTSUBNET=`cat $SAMCUSTOM |grep DESTSUBNET |grep = | awk -F "=" '{print $2}'`
KeyName=`cat $SAMCUSTOM |grep key |grep = | awk -F "=" '{print $2}'`
KeyVolume=`cat $SAMCUSTOM |grep keyname |grep = | awk -F "=" '{print $2}'`
Mail=`cat $SAMCUSTOM |grep Notice_mail |grep = | awk -F "=" '{print $2}'`
#0 import key - Disable function not too hard, do it by hands.
#aws --region $NEWREGION ec2 import-key-pair --key-name $KeyName --public-key-material $KeyVolume
#1
sudo su - root
echo "1.Check VPC" |tee -a $SAMLOG
aws --region $NEWREGION ec2 describe-vpcs >> $SAMVPC
grep $DESTIP $SAMVPC > /dev/null
if [ $? == 0 ]; then
        echo "Find VPC $DESTIP, Skip" |tee -a $SAMLOG
        VPCID=`grep $DESTIP -A100 $SAMVPC |grep VpcId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
		NEWSUBID=`aws --region $NEWREGION ec2 describe-subnets --filter Name=vpcId,Values=$VPCID |grep SubnetId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
else
        echo "Not Find VPC, Create VPC" |tee -a $SAMLOG
        aws --region $NEWREGION ec2 create-vpc --cidr-block $DESTIP > $SAMNEWVPCID
        VPCID=`cat $SAMNEWVPCID |grep VpcId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
        sleep 30
        aws --region $NEWREGION ec2 create-subnet --vpc-id $VPCID --cidr-block $DESTSUBNET |grep SubnetId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g' > $SAMNEWSUBID
        echo "Create internet GW and attach to VPC"  |tee -a $SAMLOG
        INTERNETGW=`aws --region $NEWREGION ec2 create-internet-gateway --output text |awk -F" " '{print $2}'`
        echo "Attach $INTERNETGW to $VPCID"  |tee -a $SAMLOG
        aws --region $NEWREGION ec2 attach-internet-gateway --internet-gateway-id $INTERNETGW --vpc-id $VPCID
        echo "Create RouteTable and associate route table to $VPCID"  |tee -a $SAMLOG
        ROUTETBID=`aws --region $NEWREGION ec2 describe-route-tables --filters Name=vpc-id,Values=$VPCID |grep RouteTableId |head -1 |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
        aws --region $NEWREGION ec2 create-route --route-table-id $ROUTETBID --destination-cidr-block 0.0.0.0/0 --gateway-id $INTERNETGW > /dev/null
        NEWSUBID=`cat $SAMNEWSUBID`
        aws --region $NEWREGION ec2 associate-route-table --route-table-id $ROUTETBID --subnet-id $NEWSUBID > /dev/null
fi
#2#
echo "2.Check SG" |tee -a $SAMLOG
aws --region $SOURCEREGION ec2 describe-instances --instance-ids $SOURCEINSTANCESID --query 'Reservations[*].Instances[*].[SecurityGroups[*]]' |grep GroupName |awk '{print $2}' |sed -e 's/\"//g;s/\,//g' > $SAMSOURCESGNAME
aws --region $SOURCEREGION ec2 describe-security-groups > $SAMSGINFO
aws --region $NEWREGION ec2 describe-security-groups > $SAMSGNEWINFO
for SAM in $(cat $SAMSOURCESGNAME); do
                grep $SAM $SAMSGNEWINFO > /dev/null
                if [ $? == 0 ]; then
                        echo "Find SG $SAM in new region Skip" |tee -a $SAMLOG
			aws --region $NEWREGION ec2 describe-security-groups --filter "Name=group-name,Values=$SAM" |grep GroupId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g' >> $SAMNEWSGNAME
                else
                        echo "Not find SG $SAM in new region and create" |tee -a $SAMLOG
                        aws --region $NEWREGION ec2 create-security-group --group-name $SAM --description "Copy from $SOURCEREGION" --vpc-id $VPCID --output text >> $SAMNEWSGNAME
                        echo "Create SG rule to new region $NEWREGION" |tee -a $SAMLOG
                        NEWGROUPID=`aws --region $NEWREGION ec2 describe-security-groups --filters Name=group-name,Values=$SAM |grep GroupId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
                        OLDGROUPID=`aws --region $SOURCEREGION ec2 describe-security-groups --filters Name=group-name,Values=$SAM |grep GroupId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
                        echo $NEWGROUPID $OLDGROUPID $SAM
                        aws --region $SOURCEREGION ec2 describe-security-groups --filters Name=group-name,Values=$SAM > $LOCATION/$SAM.rule
                        jq -M -r -f /var/www/html/s.jq $LOCATION/$SAM.rule > $LOCATION/$SAM.rule.sam
                        sed -i "s/$OLDGROUPID/aws --region $NEWREGION ec2 authorize-security-group-ingress --group-id $NEWGROUPID/g" $LOCATION/$SAM.rule.sam &;& chmod +x $LOCATION/$SAM.rule.sam
                        echo "Add Rule $SAM to new region $NEWREGION"
                        ( "$LOCATION/$SAM.rule.sam" )
						rm $LOCATION/$SAM.rule*
                fi
done
#3#
aws --region $SOURCEREGION ec2 describe-instances --instance-ids $SOURCEINSTANCESID --query 'Reservations[*].Instances[*]' |grep RootDeviceName |awk '{print $2}' |sed -e 's/\"//g;s/\,//g' > $SAMROOTDEVICENAME
#4#
echo "3.Create Snap" |tee -a $SAMLOG
aws --region $SOURCEREGION ec2 create-image --instance-id $SOURCEINSTANCESID --name "from$SOURCEINSTANCESID" --no-reboot |grep ImageId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g' >> $SAMIMAGEID
#5#
echo "4.Wait AMI ready and copy to new region" |tee -a $SAMLOG
IMAGEID=`cat $SAMIMAGEID`
READY=`aws --region $SOURCEREGION ec2 describe-images --image-ids $IMAGEID |grep State |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
if [ $READY != "available" ]; then
				i=0
                while [ $READY != "available" ]; do
                        sleep 60
                        READY=`aws --region $SOURCEREGION ec2 describe-images --image-ids $IMAGEID |grep State |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
						echo "Waiting snap to AMI Time passed $((i++)) Min."
                done
fi
echo "5.Copy img to newregion" |tee -a $SAMLOG
aws --region $NEWREGION ec2 copy-image --source-image-id $IMAGEID --source-region $SOURCEREGION --name "from$SOURCEINSTANCESID" |grep ImageId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g' > $SAMIMAGEIDNEW
#6#
NEWIMAGEID=`cat $SAMIMAGEIDNEW`
NEWREADY=`aws --region $NEWREGION ec2 describe-images --image-ids $NEWIMAGEID |grep State |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
if [ $NEWREADY != "available" ]; then
				i=0
                while [ $NEWREADY != "available" ]; do
                        sleep 60
                        NEWREADY=`aws --region $NEWREGION ec2 describe-images --image-ids $NEWIMAGEID |grep State |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
						echo "Waiting AMI to new region Time passed $((i++)) Min."
				done
fi
echo "AMI status is $NEWREADY now" |tee -a $SAMLOG
#Get source instance type
SAMSOURCEINSTANCETYPE=`aws --region $SOURCEREGION ec2 describe-instances --instance-ids $SOURCEINSTANCESID --query 'Reservations[*].Instances[*]' |grep InstanceType |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
SAMSOURCEKEYNAME=`aws --region $SOURCEREGION ec2 describe-instances --instance-ids $SOURCEINSTANCESID --query 'Reservations[*].Instances[*]' |grep KeyName |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
echo "New Instances info"
echo "6.Create instance in new region" |tee -a $SAMLOG
aws --region $NEWREGION ec2 run-instances --image-id $NEWIMAGEID --count 1 --instance-type $SAMSOURCEINSTANCETYPE --key-name $SAMSOURCEKEYNAME --subnet-id $NEWSUBID --associate-public-ip-address >> $SAMNEWINSTANCEINFO
NEWINSTANCEID=`cat $SAMNEWINSTANCEINFO |grep InstanceId |awk '{print $2}' |sed -e 's/\"//g;s/\,//g'`
#7#
echo "7.Attach SG groups to instance" |tee -a $SAMLOG
for SAM in $(cat $SAMNEWSGNAME); do
	echo -n $SAM" " >> $SAMSUMSGNAME
done
SAM=$(cat $SAMSUMSGNAME)
aws --region $NEWREGION ec2 modify-instance-attribute --instance-id $NEWINSTANCEID --groups $SAM
#Done
SAMTIME
echo "Finish time $NOW_TIME" |tee -a $SAMLOG
ELAPSED_TIME=$(($SECONDS - $START_TIME))
echo "Total time used $ELAPSED_TIME Seconds" |tee -a $SAMLOG
mutt -s "Auto copy ec2 $SOURCEINSTANCESID to new region info" This email address is being protected from spambots. You need JavaScript enabled to view it. < $SAMLOG
rm /$LOCATION/$$sam*

沒什麼防呆…但可以重覆執行…能多個Instances 一起複製到別的區

包含 VPC(Gateways, Route Tables, Subnets, Internet gateways, Security Groups)

以子網路判斷,沒有的話會建立,有的話跳過

最後是建立Instances snapshots, AMI, copy AMI to new region

查詢原本的instance type,比照開啟同樣的機器

網頁的部份,有兩個檔案

一個輸入值,另一個傳值到檔案去

<html><head></head>
  <body>
    <form method="post" action="store.php">
    SOURCEREGION: <input id="SOURCEREGION" name="SOURCEREGION" type="text"/><br>
    NEWREGION: <input id="NEWREGION" name="NEWREGION" type="text"/><br>
    SOURCEINSTANCESID: <input id="SOURCEINSTANCESID" name="SOURCEINSTANCESID" type="text"/><br>
    DESTIP: <input id="DESTIP" name="DESTIP" type="text"/><br>
    DESTSUBNET: <input id="DESTSUBNET" name="DESTSUBNET" type="text"/><br>
    aws_access_key_id: <input id="aws_access_key_id" name="aws_access_key_id" type="password"/><br>
    aws_secret_access_key: <input id="aws_secret_access_key" name="aws_secret_access_key" type="password"/><br>
    Notice_mail: <input id="Notice_mail" name="Notice_mail" type="text"/><br>
    <input type="submit" value="Done"/>
    </form>
  </body>
</html>
<?php
    $myfile = fopen("/var/www/html/b", "wb");
    $txt = "SOURCEREGION=".$_POST['SOURCEREGION']."\n"."NEWREGION=".$_POST['NEWREGION']."\n"."SOURCEINSTANCESID=".$_POST['SOURCEINSTANCESID']."\n"."DESTIP=".$_POST['DESTIP']."\n"."DESTSUBNET=".$_POST['DESTSUBNET']."\n"."aws_access_key_id=".$_POST['aws_access_key_id']."\n"."aws_secret_access_key=".$_POST['aws_secret_access_key']."\n"."Notice_mail=".$_POST['Notice_mail']."\n";
    fwrite($myfile, $txt);
    fclose($myfile);
    shell_exec("nohup /var/www/html/a > /dev/null 2>&;1 &");
    echo "Thanks, Script is running in background and email to you when done.<br>";
    echo "Don't press F5... will do it again...<br>";
?>

再附上一個處理aws security group的jq,方便分開security group,比用bash方便,所以獨立寫出來

root@ip-10-180-0-56:/var/www/html# cat s.jq
def ports:
   if .IpProtocol == "-1"
   then {FromPort:"all", ToPort:"all", IpProtocol:"all"}
   else {FromPort, ToPort, IpProtocol}
   end
;

def tabella($g; $p; $dir; $ip):
    [ $g.GroupId, $dir, $ip,
      "--port", $p.FromPort, "--protocol", $p.IpProtocol ]
;

def creatab:
      .SecurityGroups[]
    | { GroupId, } as $g
    | (
          .IpPermissions[]
        | ports as $p
        | ( .IpRanges[]         | tabella($g; $p; "--cidr"; .CidrIp) ),
          ( .UserIdGroupPairs[] | tabella($g; $p; "--cidr"; .GroupId) )
      )
;

  creatab
| map(tostring)
| join(" ")