ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãããããšã§èŠåŽããç¹ãããïŒ åç·šåç
§ ïŒãå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãã åç·šã§ã¯ Proxy å±€ã®æ§æãšããŠã䞻㫠Nginx ã䜿çšãã Path Based Routing åšãã«ã€ããŠã®ã話ã§ãããåŸç·šã§ã¯ App å±€ã§äœ¿çšãã EC2ã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æããããŸãã App å±€ã®æ§æ App å±€ã®æ¹éãæ§ç¯ã®æµãçããŸãšãããšä»¥äžã®éãã§ãã ãŽãŒã«ãã³ã€ã¡ãŒãžãšã㊠OS èšå®ããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ãã imageïŒAMIïŒãäœæããŠãã äžèšã® AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãæ¯ã« EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãã ã€ã³ã¹ã¿ã³ã¹äœææã«å¿
èŠãª Tag ã®å€ãç°å¢å€æ°ãèšå®ããŠãã ç°å¢å€æ°ã¯ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² EC2 ã€ã³ã¹ã¿ã³ã¹èµ·åæã«ãã¯ã©ã€ã¢ã³ãã«å¿ãã Tag ãç°å¢å€æ°ãããšã«ãµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãããè¡ã èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ããã§ã¯ãããããã®è©³çްã«ã€ããŠèª¬æããŠãããããšæããŸãã AMI äœæ Packer ã䜿çšããŠåã€ã³ã¹ã¿ã³ã¹å
±éãšãªã AMI ãäœæããŸãã provisioners ã§æå®ããæ§ç¯çšã¹ã¯ãªããã§ OS èšå®ãå¿
èŠã©ã€ãã©ãªããŸãã¡ã€ã³ãšãªããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããŸãããŸããcloud-init ã䜿çšããŠååèµ·åæã«åããã¹ã¯ãªããé¡ãã³ããŒããŠãããŸãã ãªããcloud-init ããå®è¡ããã¹ã¯ãªãã㯠Git ã S3 ãªã©ããåçã«ååŸããæ¹æ³ããããŸããããã»ã©ã¹ã¯ãªããã®å
容ã«å€æŽã¯çºçããªãç¹ãšãå
容çã«å€æŽããå Žå㯠image åäœæãã©ã¡ãã«ããŠãå¿
èŠã«ãªãããã ã£ãã®ã§å²ãåã£ãŠ image å
ã«å«ããããšã«ããŠããŸãã äœæãã packer.json ã® provisioners éšåãæç²ãããšãã®ãããªæãã«ãªããŸãïŒèª¬æã³ã¡ã³ãéšåã¯å®éã«ã¯èšèŒããŠããŸããïŒ "provisioners" : [ -- type: shell ãšããŠãæ§ç¯çšã¹ã¯ãªããæå®ããã«ãæã«å®è¡ããã { "type" : "shell" , "scripts" : [ "scripts/provision.sh" ] }, -- type: file ã§ã€ã³ã¹ã¿ã³ã¹èµ·åæã«å®è¡ãããã¹ã¯ãªãã矀ãã³ã㌠-- ãããã®ã¹ã¯ãªãã㯠cloud-init ããå®è¡ãããïŒcloud-init ã®èšå®ã¯å¥éã€ã³ã¹ã¿ã³ã¹äœææã«è¡ã£ãŠããïŒ { "type" : "file" , "source" : "./scripts" , "destination" : "/home/hoge" }, -- äžèšã®ã¹ã¯ãªããã«å¯ŸããŠå®è¡æš©éä»äž { "type" : "shell" , "inline" : [ "chmod +x /home/hoge/scripts/*" ] } ] packer build ã§ãã«ããã image ã AWS ã«ä»åã®å
±éã§äœ¿çšãã AMI ãšããŠç»é²ãããŸã EC2 ã€ã³ã¹ã¿ã³ã¹äœæ äœæãã AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãããšã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãããªããã€ã³ã¹ã¿ã³ã¹äœæã¯ Terraform ã CloudFormation ãªã©ã¯äœ¿ãããAWS CLI ãå©çšããã¹ã¯ãªãããäœæããŠå®è¡ããŠããŸãã ã€ã³ã¹ã¿ã³ã¹äœæã¹ã¯ãªããã¯ãã®ãããªæµãã®åŠçãšãªããŸãã åŒæ°ã§ã¯ã©ã€ã¢ã³ãèå¥ ID ããã®ä»ãµãŒãã¢ããªã±ãŒã·ã§ã³ã»ããã¢ããã«å¿
èŠãšãªãç°å¢å€æ°ãæå® AWS CLI ã§ EC2 ã€ã³ã¹ã¿ã³ã¹äœæ åŒæ°ã§æå®ãããç°å¢å€æ°ã AWS CLI ã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² ã€ã³ã¹ã¿ã³ã¹äœæ 以äžã®ããã«ã aws ec2 run-instances ã³ãã³ãã䜿çšããTag ã«ã¯ã©ã€ã¢ã³ãèå¥ ID ãæå®ããŠäœæããŠããŸãã ããã§æå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«ãã©ã¡ãŒã¿ã¹ãã¢ããèªåçšã®ç°å¢å€æ°ãç»é²/ååŸããããPrivate DNS çšã®ãã¡ã€ã³ã«äœ¿çšããŸãã aws ec2 run-instances \ --image-id ${ AMI_ID } \ --key-name ${ KEY_NAME } --region ${ REGION } \ --subnet-id ${ SUBNET_ID } \ --security-group-ids ${ SECURITY_GROUP } \ --user-data file:// ${ USER_DATA } \ --instance-type ${ INSTANCE_TYPE } \ --tag-specifications "ResourceType=instance,Tags=[{Key=ClientId,Value=${ CLIENT_ID }}]" \ --iam-instance-profile "Arn=${ SERVICE_ROLE }" user-data ã«ã¯ååèµ·åæã«å®è¡ãããã¹ã¯ãªããïŒPacker ã§ãã«ãæã«ã³ããŒããŠãããã¹ã¯ãªããïŒãæå®ããŠããã ããšãªããŸãã #!/bin/bash /home/hoge/scripts/bootstrap.sh ãã©ã¡ãŒã¿ã¹ãã¢ã«ç°å¢å€æ°ç»é² 䜿çšããç°å¢å€æ°ã¯ãKey ã¯å
±éã§ããå€ãã¯ã©ã€ã¢ã³ãã«ãã£ãŠç°ãªããŸãããã®ãããHOGE ãšãã Key ã䜿çšããå Žåã <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é²ããŠããŸãã ïŒæ³š. ãã©ã¡ãŒã¿ã¹ãã¢ã« éå±€ãã¿ã°ä»ãããµããŒãããã ãããããã®ãããã®æ§æã¯ä»åŸèŠçŽãäºå®ã§ãïŒ ç»é²ã¯ aws ssm put-parameter ãå®è¡ããŸã aws ssm put-parameter \ --name ${ KEY } \ --value ${ VALUE } \ --type ${ PARAMETER_TYPE } \ # StringãSecureString ãªã© --overwrite ããã§ã¯ã©ã€ã¢ã³ãããšã® EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãèµ·åãããŸããæ¬¡ã«ã€ã³ã¹ã¿ã³ã¹èµ·åæã®æµãã«ã€ããŠã§ãã EC2 ã€ã³ã¹ã¿ã³ã¹èµ·å èµ·åæã¯ãååèµ·åãšæ¯åèµ·åã§ãããã以äžã®ãããªåŠçãè¡ããŸãã åå: ãã©ã¡ãŒã¿ã¹ãã¢ããèªèº«ã«é¢é£ããç°å¢å€æ°ãååŸãããµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãã æ¯å: èªèº«ã®å
éš IP ã Route53 ã® Private DNS ã«ç»é²/æŽæ° å
éš IP ã¯åºå®ããŠãããèµ·åæã«å²ãæ¯ããããããæ¯åæŽæ°ããããã«ããŠããŸãã ããã§ã¯ããããã®å
容ã«ã€ããŠèŠãŠãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ããç°å¢å€æ°ååŸ ç»é²æã®å
容ã§èšèŒããŸããããç°å¢å€æ°ã¯ <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ç»é²ããŠããŸãããã®ããããŸãã¯èªèº«ã®ã¯ã©ã€ã¢ã³ãèå¥ ID ãå€å®ããåŸã«å¿
èŠãªç°å¢å€æ°ã aws ssm get-parameters ã§ååŸããŸãã # èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãã¡ã¿ããŒã¿ããååŸ INSTANCE_ID =$( curl -s https://169.254.169.254/latest/meta-data/instance-id ) # ã¯ã©ã€ã¢ã³ãèå¥ ID ãã€ã³ã¹ã¿ã³ã¹äœææã«æå®ãã Tag ããååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) CLIENT_ID_TAG =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].Tags[] | select(.Key == "ClientId").Value' ) # ç°å¢å€æ°ãååŸ # ã¿ã€ãã SecureString ã«ããŠãã倿°ããããããäžåŸ --with-decryption ãªãã·ã§ã³ãæå®ããŠãã HOGE =$( aws ssm get-parameters \ --name "${ CLIENT_ID_TAG }.HOGE" \ --with-decryption --region ${ REGION } \ | jq -r ".Parameters[].Value" ) export HOGE =${ HOGE } å
éš IP ã Private DNS ã«ç»é² æåŸã«ãProxy å±€ãã Private DNS ã§åå解決ã§ããããã«èªèº«ã® IP ã Route 53 ã«ç»é²ããŠãããŸãã ãªããRoute53 ã«ã¯äºåã«å¯Ÿè±¡ã® Hosted Zone ã Private Hosted Zone for Amazon VPC ã¿ã€ããšããŠç»é²ããŠãããŸããããã§ã¯äŸãšã㊠Domain Name ã local ãšããŸãã EC2 ã€ã³ã¹ã¿ã³ã¹ããç»é²ããã RecordSet ã¯ä»¥äžã®åœ¢åŒãšããŸãã Name: <ã¯ã©ã€ã¢ã³ãèå¥ ID>.local Type: CNAME Value: EC2 ã€ã³ã¹ã¿ã³ã¹ã®å
éš IP ããããè¡ãã¹ã¯ãªããäŸã¯ä»¥äžãšãªããŸãã # å
éš IP ãååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) PRIVATE_IP =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].PrivateIpAddress' ) # Route53 ã®ç»é²å
Hosted Zone ID ãååŸ # SEARCH_KEY ã¯ä»åã®äŸã§ãããš 'local.' ã«ãªããŸã HOSTED_ZONE_ID =$( aws route53 list-hosted-zones \ --region=${ REGION } \ | jq -r ".HostedZones[] | select(.Name == \" ${ SEARCH_KEY } \" ).Id" ) # ãã®åŸã®ç»é²ã³ãã³ãã§æå®ããããã®å®çŸ©ãã¡ã€ã« # æ¯èµ·åæã®ç»é²çšïŒIP ãå€ããããïŒã«ãAction ã«ã¯ 'UPSERT' ãæå® RECORDSET_FILE = "/tmp/create_recordset.json" cat << EOT > ${ RECORDSET_FILE } { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "<ã¯ã©ã€ã¢ã³ãèå¥ ID>.local", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "${ PRIVATE_IP }" } ] } } ] } EOT # äœæããå®çŸ©ãã¡ã€ã«ãæå®ããRoute53 ã«ç»é² aws route53 change-resource-record-sets \ --hosted-zone-id ${ HOSTED_ZONE_ID } \ --change-batch file:/// ${ RECORDSET_FILE } å®è¡ããã¹ãããã¯ããå€ãã§ããããã®ãããªæ§æããšãããšã§ VPC å
ã§ã¯ãã¡ã€ã³æå®ã§ã®ã¢ã¯ã»ã¹ãå¯èœãšãªããããIP ãæèããå¿
èŠããªããªãããæè»ãªæ§æã«ãªãããšæããŸãã ä»åã®ãŸãšã ããŸããã€ã³ã¹ã¿ã³ã¹ç«ãŠããšãããã©ããããªãããããšãæããªããè²ã
調ã¹ãŠæ§ç¯ããŸããããEC2 ãŸããã®ãµãŒãã¹ãå¢ããŠããã ãªãããªããŠæããŸããïŒç¹ã«ãã©ã¡ãŒã¿ã¹ãã¢ã¯ãšãŠã䟿å©ïŒ ãã©ã¡ãŒã¿ã¹ãã¢ä»¥å€ã«ã Systems Manager ã«ã¯ Run Command ã Patch Manager ãªã© EC2 ã€ã³ã¹ã¿ã³ã¹ã管çããäžã§ãšãŠã䟿å©ãªä»çµã¿ãæã£ãŠããŸãã®ã§ãã®ããããå°å
¥ããŠãããããšæããŸãã äœè«ã§ãããSystems Manager ã®ååšã¯ re:Invent 2016 ã§çºè¡šãããæããååã ãã¯ç¥ã£ãŠãŸããããä»åã®å¯Ÿå¿ãããŸã§ãã£ãšãªã³ãã¬å°çšã®ãµãŒãã¹ã ãšåéãããŠãŠèšæ¶ããæ¶ããããŠããŸããããã æåŸã« åç·šã Proxy å±€ ïŒNginxïŒãåŸç·šã App å±€ïŒEC2ïŒã«ã€ããŠæžãããŠããã ããŸããããããã ã£ãã§ããããã ããããã®èŠä»¶èªäœããã£ããç¹æ®ã ã£ãããããã®ã§ããªãã§ãããªæ§æã«ïŒã¿ãããªãšããããããç¥ããŸããããã©ãªããã®åèã«ãªãã°å¹žãã§ããããå°ãèããŠã¿ããããšãããã㯠wantedly ã®ã 話ãèããŠã¿ãã ããã¿ã³ããã©ããã â»åç·šããããããŠèªã¿ããæ¹ã¯ãã¡ãããã©ãã https://developer.medley.jp/entry/2017/08/24/120000_01 ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãããããšã§èŠåŽããç¹ãããïŒ åç·šåç
§ ïŒãå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãã åç·šã§ã¯ Proxy å±€ã®æ§æãšããŠã䞻㫠Nginx ã䜿çšãã Path Based Routing åšãã«ã€ããŠã®ã話ã§ãããåŸç·šã§ã¯ App å±€ã§äœ¿çšãã EC2ã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æããããŸãã App å±€ã®æ§æ App å±€ã®æ¹éãæ§ç¯ã®æµãçããŸãšãããšä»¥äžã®éãã§ãã ãŽãŒã«ãã³ã€ã¡ãŒãžãšã㊠OS èšå®ããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ãã imageïŒAMIïŒãäœæããŠãã äžèšã® AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãæ¯ã« EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãã ã€ã³ã¹ã¿ã³ã¹äœææã«å¿
èŠãª Tag ã®å€ãç°å¢å€æ°ãèšå®ããŠãã ç°å¢å€æ°ã¯ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² EC2 ã€ã³ã¹ã¿ã³ã¹èµ·åæã«ãã¯ã©ã€ã¢ã³ãã«å¿ãã Tag ãç°å¢å€æ°ãããšã«ãµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãããè¡ã èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ããã§ã¯ãããããã®è©³çްã«ã€ããŠèª¬æããŠãããããšæããŸãã AMI äœæ Packer ã䜿çšããŠåã€ã³ã¹ã¿ã³ã¹å
±éãšãªã AMI ãäœæããŸãã provisioners ã§æå®ããæ§ç¯çšã¹ã¯ãªããã§ OS èšå®ãå¿
èŠã©ã€ãã©ãªããŸãã¡ã€ã³ãšãªããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããŸãããŸããcloud-init ã䜿çšããŠååèµ·åæã«åããã¹ã¯ãªããé¡ãã³ããŒããŠãããŸãã ãªããcloud-init ããå®è¡ããã¹ã¯ãªãã㯠Git ã S3 ãªã©ããåçã«ååŸããæ¹æ³ããããŸããããã»ã©ã¹ã¯ãªããã®å
容ã«å€æŽã¯çºçããªãç¹ãšãå
容çã«å€æŽããå Žå㯠image åäœæãã©ã¡ãã«ããŠãå¿
èŠã«ãªãããã ã£ãã®ã§å²ãåã£ãŠ image å
ã«å«ããããšã«ããŠããŸãã äœæãã packer.json ã® provisioners éšåãæç²ãããšãã®ãããªæãã«ãªããŸãïŒèª¬æã³ã¡ã³ãéšåã¯å®éã«ã¯èšèŒããŠããŸããïŒ "provisioners" : [ -- type: shell ãšããŠãæ§ç¯çšã¹ã¯ãªããæå®ããã«ãæã«å®è¡ããã { "type" : "shell" , "scripts" : [ "scripts/provision.sh" ] }, -- type: file ã§ã€ã³ã¹ã¿ã³ã¹èµ·åæã«å®è¡ãããã¹ã¯ãªãã矀ãã³ã㌠-- ãããã®ã¹ã¯ãªãã㯠cloud-init ããå®è¡ãããïŒcloud-init ã®èšå®ã¯å¥éã€ã³ã¹ã¿ã³ã¹äœææã«è¡ã£ãŠããïŒ { "type" : "file" , "source" : "./scripts" , "destination" : "/home/hoge" }, -- äžèšã®ã¹ã¯ãªããã«å¯ŸããŠå®è¡æš©éä»äž { "type" : "shell" , "inline" : [ "chmod +x /home/hoge/scripts/*" ] } ] packer build ã§ãã«ããã image ã AWS ã«ä»åã®å
±éã§äœ¿çšãã AMI ãšããŠç»é²ãããŸã EC2 ã€ã³ã¹ã¿ã³ã¹äœæ äœæãã AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãããšã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãããªããã€ã³ã¹ã¿ã³ã¹äœæã¯ Terraform ã CloudFormation ãªã©ã¯äœ¿ãããAWS CLI ãå©çšããã¹ã¯ãªãããäœæããŠå®è¡ããŠããŸãã ã€ã³ã¹ã¿ã³ã¹äœæã¹ã¯ãªããã¯ãã®ãããªæµãã®åŠçãšãªããŸãã åŒæ°ã§ã¯ã©ã€ã¢ã³ãèå¥ ID ããã®ä»ãµãŒãã¢ããªã±ãŒã·ã§ã³ã»ããã¢ããã«å¿
èŠãšãªãç°å¢å€æ°ãæå® AWS CLI ã§ EC2 ã€ã³ã¹ã¿ã³ã¹äœæ åŒæ°ã§æå®ãããç°å¢å€æ°ã AWS CLI ã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² ã€ã³ã¹ã¿ã³ã¹äœæ 以äžã®ããã«ã aws ec2 run-instances ã³ãã³ãã䜿çšããTag ã«ã¯ã©ã€ã¢ã³ãèå¥ ID ãæå®ããŠäœæããŠããŸãã ããã§æå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«ãã©ã¡ãŒã¿ã¹ãã¢ããèªåçšã®ç°å¢å€æ°ãç»é²/ååŸããããPrivate DNS çšã®ãã¡ã€ã³ã«äœ¿çšããŸãã aws ec2 run-instances \ --image-id ${ AMI_ID } \ --key-name ${ KEY_NAME } --region ${ REGION } \ --subnet-id ${ SUBNET_ID } \ --security-group-ids ${ SECURITY_GROUP } \ --user-data file:// ${ USER_DATA } \ --instance-type ${ INSTANCE_TYPE } \ --tag-specifications "ResourceType=instance,Tags=[{Key=ClientId,Value=${ CLIENT_ID }}]" \ --iam-instance-profile "Arn=${ SERVICE_ROLE }" user-data ã«ã¯ååèµ·åæã«å®è¡ãããã¹ã¯ãªããïŒPacker ã§ãã«ãæã«ã³ããŒããŠãããã¹ã¯ãªããïŒãæå®ããŠããã ããšãªããŸãã #!/bin/bash /home/hoge/scripts/bootstrap.sh ãã©ã¡ãŒã¿ã¹ãã¢ã«ç°å¢å€æ°ç»é² 䜿çšããç°å¢å€æ°ã¯ãKey ã¯å
±éã§ããå€ãã¯ã©ã€ã¢ã³ãã«ãã£ãŠç°ãªããŸãããã®ãããHOGE ãšãã Key ã䜿çšããå Žåã <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é²ããŠããŸãã ïŒæ³š. ãã©ã¡ãŒã¿ã¹ãã¢ã« éå±€ãã¿ã°ä»ãããµããŒãããã ãããããã®ãããã®æ§æã¯ä»åŸèŠçŽãäºå®ã§ãïŒ ç»é²ã¯ aws ssm put-parameter ãå®è¡ããŸã aws ssm put-parameter \ --name ${ KEY } \ --value ${ VALUE } \ --type ${ PARAMETER_TYPE } \ # StringãSecureString ãªã© --overwrite ããã§ã¯ã©ã€ã¢ã³ãããšã® EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãèµ·åãããŸããæ¬¡ã«ã€ã³ã¹ã¿ã³ã¹èµ·åæã®æµãã«ã€ããŠã§ãã EC2 ã€ã³ã¹ã¿ã³ã¹èµ·å èµ·åæã¯ãååèµ·åãšæ¯åèµ·åã§ãããã以äžã®ãããªåŠçãè¡ããŸãã åå: ãã©ã¡ãŒã¿ã¹ãã¢ããèªèº«ã«é¢é£ããç°å¢å€æ°ãååŸãããµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãã æ¯å: èªèº«ã®å
éš IP ã Route53 ã® Private DNS ã«ç»é²/æŽæ° å
éš IP ã¯åºå®ããŠãããèµ·åæã«å²ãæ¯ããããããæ¯åæŽæ°ããããã«ããŠããŸãã ããã§ã¯ããããã®å
容ã«ã€ããŠèŠãŠãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ããç°å¢å€æ°ååŸ ç»é²æã®å
容ã§èšèŒããŸããããç°å¢å€æ°ã¯ <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ç»é²ããŠããŸãããã®ããããŸãã¯èªèº«ã®ã¯ã©ã€ã¢ã³ãèå¥ ID ãå€å®ããåŸã«å¿
èŠãªç°å¢å€æ°ã aws ssm get-parameters ã§ååŸããŸãã # èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãã¡ã¿ããŒã¿ããååŸ INSTANCE_ID =$( curl -s https://169.254.169.254/latest/meta-data/instance-id ) # ã¯ã©ã€ã¢ã³ãèå¥ ID ãã€ã³ã¹ã¿ã³ã¹äœææã«æå®ãã Tag ããååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) CLIENT_ID_TAG =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].Tags[] | select(.Key == "ClientId").Value' ) # ç°å¢å€æ°ãååŸ # ã¿ã€ãã SecureString ã«ããŠãã倿°ããããããäžåŸ --with-decryption ãªãã·ã§ã³ãæå®ããŠãã HOGE =$( aws ssm get-parameters \ --name "${ CLIENT_ID_TAG }.HOGE" \ --with-decryption --region ${ REGION } \ | jq -r ".Parameters[].Value" ) export HOGE =${ HOGE } å
éš IP ã Private DNS ã«ç»é² æåŸã«ãProxy å±€ãã Private DNS ã§åå解決ã§ããããã«èªèº«ã® IP ã Route 53 ã«ç»é²ããŠãããŸãã ãªããRoute53 ã«ã¯äºåã«å¯Ÿè±¡ã® Hosted Zone ã Private Hosted Zone for Amazon VPC ã¿ã€ããšããŠç»é²ããŠãããŸããããã§ã¯äŸãšã㊠Domain Name ã local ãšããŸãã EC2 ã€ã³ã¹ã¿ã³ã¹ããç»é²ããã RecordSet ã¯ä»¥äžã®åœ¢åŒãšããŸãã Name: <ã¯ã©ã€ã¢ã³ãèå¥ ID>.local Type: CNAME Value: EC2 ã€ã³ã¹ã¿ã³ã¹ã®å
éš IP ããããè¡ãã¹ã¯ãªããäŸã¯ä»¥äžãšãªããŸãã # å
éš IP ãååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) PRIVATE_IP =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].PrivateIpAddress' ) # Route53 ã®ç»é²å
Hosted Zone ID ãååŸ # SEARCH_KEY ã¯ä»åã®äŸã§ãããš 'local.' ã«ãªããŸã HOSTED_ZONE_ID =$( aws route53 list-hosted-zones \ --region=${ REGION } \ | jq -r ".HostedZones[] | select(.Name == \" ${ SEARCH_KEY } \" ).Id" ) # ãã®åŸã®ç»é²ã³ãã³ãã§æå®ããããã®å®çŸ©ãã¡ã€ã« # æ¯èµ·åæã®ç»é²çšïŒIP ãå€ããããïŒã«ãAction ã«ã¯ 'UPSERT' ãæå® RECORDSET_FILE = "/tmp/create_recordset.json" cat << EOT > ${ RECORDSET_FILE } { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "<ã¯ã©ã€ã¢ã³ãèå¥ ID>.local", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "${ PRIVATE_IP }" } ] } } ] } EOT # äœæããå®çŸ©ãã¡ã€ã«ãæå®ããRoute53 ã«ç»é² aws route53 change-resource-record-sets \ --hosted-zone-id ${ HOSTED_ZONE_ID } \ --change-batch file:/// ${ RECORDSET_FILE } å®è¡ããã¹ãããã¯ããå€ãã§ããããã®ãããªæ§æããšãããšã§ VPC å
ã§ã¯ãã¡ã€ã³æå®ã§ã®ã¢ã¯ã»ã¹ãå¯èœãšãªããããIP ãæèããå¿
èŠããªããªãããæè»ãªæ§æã«ãªãããšæããŸãã ä»åã®ãŸãšã ããŸããã€ã³ã¹ã¿ã³ã¹ç«ãŠããšãããã©ããããªãããããšãæããªããè²ã
調ã¹ãŠæ§ç¯ããŸããããEC2 ãŸããã®ãµãŒãã¹ãå¢ããŠããã ãªãããªããŠæããŸããïŒç¹ã«ãã©ã¡ãŒã¿ã¹ãã¢ã¯ãšãŠã䟿å©ïŒ ãã©ã¡ãŒã¿ã¹ãã¢ä»¥å€ã«ã Systems Manager ã«ã¯ Run Command ã Patch Manager ãªã© EC2 ã€ã³ã¹ã¿ã³ã¹ã管çããäžã§ãšãŠã䟿å©ãªä»çµã¿ãæã£ãŠããŸãã®ã§ãã®ããããå°å
¥ããŠãããããšæããŸãã äœè«ã§ãããSystems Manager ã®ååšã¯ re:Invent 2016 ã§çºè¡šãããæããååã ãã¯ç¥ã£ãŠãŸããããä»åã®å¯Ÿå¿ãããŸã§ãã£ãšãªã³ãã¬å°çšã®ãµãŒãã¹ã ãšåéãããŠãŠèšæ¶ããæ¶ããããŠããŸããããã æåŸã« åç·šã Proxy å±€ ïŒNginxïŒãåŸç·šã App å±€ïŒEC2ïŒã«ã€ããŠæžãããŠããã ããŸããããããã ã£ãã§ããããã ããããã®èŠä»¶èªäœããã£ããç¹æ®ã ã£ãããããã®ã§ããªãã§ãããªæ§æã«ïŒã¿ãããªãšããããããç¥ããŸããããã©ãªããã®åèã«ãªãã°å¹žãã§ããããå°ãèããŠã¿ããããšãããã㯠wantedly ã®ã 話ãèããŠã¿ãã ããã¿ã³ããã©ããã â»åç·šããããããŠèªã¿ããæ¹ã¯ãã¡ãããã©ãã https://developer.medley.jp/entry/2017/08/24/120000_01 ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãããããšã§èŠåŽããç¹ãããïŒ åç·šåç
§ ïŒãå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãã åç·šã§ã¯ Proxy å±€ã®æ§æãšããŠã䞻㫠Nginx ã䜿çšãã Path Based Routing åšãã«ã€ããŠã®ã話ã§ãããåŸç·šã§ã¯ App å±€ã§äœ¿çšãã EC2ã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æããããŸãã App å±€ã®æ§æ App å±€ã®æ¹éãæ§ç¯ã®æµãçããŸãšãããšä»¥äžã®éãã§ãã ãŽãŒã«ãã³ã€ã¡ãŒãžãšã㊠OS èšå®ããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ãã imageïŒAMIïŒãäœæããŠãã äžèšã® AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãæ¯ã« EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãã ã€ã³ã¹ã¿ã³ã¹äœææã«å¿
èŠãª Tag ã®å€ãç°å¢å€æ°ãèšå®ããŠãã ç°å¢å€æ°ã¯ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² EC2 ã€ã³ã¹ã¿ã³ã¹èµ·åæã«ãã¯ã©ã€ã¢ã³ãã«å¿ãã Tag ãç°å¢å€æ°ãããšã«ãµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãããè¡ã èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ããã§ã¯ãããããã®è©³çްã«ã€ããŠèª¬æããŠãããããšæããŸãã AMI äœæ Packer ã䜿çšããŠåã€ã³ã¹ã¿ã³ã¹å
±éãšãªã AMI ãäœæããŸãã provisioners ã§æå®ããæ§ç¯çšã¹ã¯ãªããã§ OS èšå®ãå¿
èŠã©ã€ãã©ãªããŸãã¡ã€ã³ãšãªããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããŸãããŸããcloud-init ã䜿çšããŠååèµ·åæã«åããã¹ã¯ãªããé¡ãã³ããŒããŠãããŸãã ãªããcloud-init ããå®è¡ããã¹ã¯ãªãã㯠Git ã S3 ãªã©ããåçã«ååŸããæ¹æ³ããããŸããããã»ã©ã¹ã¯ãªããã®å
容ã«å€æŽã¯çºçããªãç¹ãšãå
容çã«å€æŽããå Žå㯠image åäœæãã©ã¡ãã«ããŠãå¿
èŠã«ãªãããã ã£ãã®ã§å²ãåã£ãŠ image å
ã«å«ããããšã«ããŠããŸãã äœæãã packer.json ã® provisioners éšåãæç²ãããšãã®ãããªæãã«ãªããŸãïŒèª¬æã³ã¡ã³ãéšåã¯å®éã«ã¯èšèŒããŠããŸããïŒ "provisioners" : [ -- type: shell ãšããŠãæ§ç¯çšã¹ã¯ãªããæå®ããã«ãæã«å®è¡ããã { "type" : "shell" , "scripts" : [ "scripts/provision.sh" ] }, -- type: file ã§ã€ã³ã¹ã¿ã³ã¹èµ·åæã«å®è¡ãããã¹ã¯ãªãã矀ãã³ã㌠-- ãããã®ã¹ã¯ãªãã㯠cloud-init ããå®è¡ãããïŒcloud-init ã®èšå®ã¯å¥éã€ã³ã¹ã¿ã³ã¹äœææã«è¡ã£ãŠããïŒ { "type" : "file" , "source" : "./scripts" , "destination" : "/home/hoge" }, -- äžèšã®ã¹ã¯ãªããã«å¯ŸããŠå®è¡æš©éä»äž { "type" : "shell" , "inline" : [ "chmod +x /home/hoge/scripts/*" ] } ] packer build ã§ãã«ããã image ã AWS ã«ä»åã®å
±éã§äœ¿çšãã AMI ãšããŠç»é²ãããŸã EC2 ã€ã³ã¹ã¿ã³ã¹äœæ äœæãã AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãããšã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãããªããã€ã³ã¹ã¿ã³ã¹äœæã¯ Terraform ã CloudFormation ãªã©ã¯äœ¿ãããAWS CLI ãå©çšããã¹ã¯ãªãããäœæããŠå®è¡ããŠããŸãã ã€ã³ã¹ã¿ã³ã¹äœæã¹ã¯ãªããã¯ãã®ãããªæµãã®åŠçãšãªããŸãã åŒæ°ã§ã¯ã©ã€ã¢ã³ãèå¥ ID ããã®ä»ãµãŒãã¢ããªã±ãŒã·ã§ã³ã»ããã¢ããã«å¿
èŠãšãªãç°å¢å€æ°ãæå® AWS CLI ã§ EC2 ã€ã³ã¹ã¿ã³ã¹äœæ åŒæ°ã§æå®ãããç°å¢å€æ°ã AWS CLI ã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² ã€ã³ã¹ã¿ã³ã¹äœæ 以äžã®ããã«ã aws ec2 run-instances ã³ãã³ãã䜿çšããTag ã«ã¯ã©ã€ã¢ã³ãèå¥ ID ãæå®ããŠäœæããŠããŸãã ããã§æå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«ãã©ã¡ãŒã¿ã¹ãã¢ããèªåçšã®ç°å¢å€æ°ãç»é²/ååŸããããPrivate DNS çšã®ãã¡ã€ã³ã«äœ¿çšããŸãã aws ec2 run-instances \ --image-id ${ AMI_ID } \ --key-name ${ KEY_NAME } --region ${ REGION } \ --subnet-id ${ SUBNET_ID } \ --security-group-ids ${ SECURITY_GROUP } \ --user-data file:// ${ USER_DATA } \ --instance-type ${ INSTANCE_TYPE } \ --tag-specifications "ResourceType=instance,Tags=[{Key=ClientId,Value=${ CLIENT_ID }}]" \ --iam-instance-profile "Arn=${ SERVICE_ROLE }" user-data ã«ã¯ååèµ·åæã«å®è¡ãããã¹ã¯ãªããïŒPacker ã§ãã«ãæã«ã³ããŒããŠãããã¹ã¯ãªããïŒãæå®ããŠããã ããšãªããŸãã #!/bin/bash /home/hoge/scripts/bootstrap.sh ãã©ã¡ãŒã¿ã¹ãã¢ã«ç°å¢å€æ°ç»é² 䜿çšããç°å¢å€æ°ã¯ãKey ã¯å
±éã§ããå€ãã¯ã©ã€ã¢ã³ãã«ãã£ãŠç°ãªããŸãããã®ãããHOGE ãšãã Key ã䜿çšããå Žåã <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é²ããŠããŸãã ïŒæ³š. ãã©ã¡ãŒã¿ã¹ãã¢ã« éå±€ãã¿ã°ä»ãããµããŒãããã ãããããã®ãããã®æ§æã¯ä»åŸèŠçŽãäºå®ã§ãïŒ ç»é²ã¯ aws ssm put-parameter ãå®è¡ããŸã aws ssm put-parameter \ --name ${ KEY } \ --value ${ VALUE } \ --type ${ PARAMETER_TYPE } \ # StringãSecureString ãªã© --overwrite ããã§ã¯ã©ã€ã¢ã³ãããšã® EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãèµ·åãããŸããæ¬¡ã«ã€ã³ã¹ã¿ã³ã¹èµ·åæã®æµãã«ã€ããŠã§ãã EC2 ã€ã³ã¹ã¿ã³ã¹èµ·å èµ·åæã¯ãååèµ·åãšæ¯åèµ·åã§ãããã以äžã®ãããªåŠçãè¡ããŸãã åå: ãã©ã¡ãŒã¿ã¹ãã¢ããèªèº«ã«é¢é£ããç°å¢å€æ°ãååŸãããµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãã æ¯å: èªèº«ã®å
éš IP ã Route53 ã® Private DNS ã«ç»é²/æŽæ° å
éš IP ã¯åºå®ããŠãããèµ·åæã«å²ãæ¯ããããããæ¯åæŽæ°ããããã«ããŠããŸãã ããã§ã¯ããããã®å
容ã«ã€ããŠèŠãŠãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ããç°å¢å€æ°ååŸ ç»é²æã®å
容ã§èšèŒããŸããããç°å¢å€æ°ã¯ <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ç»é²ããŠããŸãããã®ããããŸãã¯èªèº«ã®ã¯ã©ã€ã¢ã³ãèå¥ ID ãå€å®ããåŸã«å¿
èŠãªç°å¢å€æ°ã aws ssm get-parameters ã§ååŸããŸãã # èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãã¡ã¿ããŒã¿ããååŸ INSTANCE_ID =$( curl -s https://169.254.169.254/latest/meta-data/instance-id ) # ã¯ã©ã€ã¢ã³ãèå¥ ID ãã€ã³ã¹ã¿ã³ã¹äœææã«æå®ãã Tag ããååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) CLIENT_ID_TAG =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].Tags[] | select(.Key == "ClientId").Value' ) # ç°å¢å€æ°ãååŸ # ã¿ã€ãã SecureString ã«ããŠãã倿°ããããããäžåŸ --with-decryption ãªãã·ã§ã³ãæå®ããŠãã HOGE =$( aws ssm get-parameters \ --name "${ CLIENT_ID_TAG }.HOGE" \ --with-decryption --region ${ REGION } \ | jq -r ".Parameters[].Value" ) export HOGE =${ HOGE } å
éš IP ã Private DNS ã«ç»é² æåŸã«ãProxy å±€ãã Private DNS ã§åå解決ã§ããããã«èªèº«ã® IP ã Route 53 ã«ç»é²ããŠãããŸãã ãªããRoute53 ã«ã¯äºåã«å¯Ÿè±¡ã® Hosted Zone ã Private Hosted Zone for Amazon VPC ã¿ã€ããšããŠç»é²ããŠãããŸããããã§ã¯äŸãšã㊠Domain Name ã local ãšããŸãã EC2 ã€ã³ã¹ã¿ã³ã¹ããç»é²ããã RecordSet ã¯ä»¥äžã®åœ¢åŒãšããŸãã Name: <ã¯ã©ã€ã¢ã³ãèå¥ ID>.local Type: CNAME Value: EC2 ã€ã³ã¹ã¿ã³ã¹ã®å
éš IP ããããè¡ãã¹ã¯ãªããäŸã¯ä»¥äžãšãªããŸãã # å
éš IP ãååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) PRIVATE_IP =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].PrivateIpAddress' ) # Route53 ã®ç»é²å
Hosted Zone ID ãååŸ # SEARCH_KEY ã¯ä»åã®äŸã§ãããš 'local.' ã«ãªããŸã HOSTED_ZONE_ID =$( aws route53 list-hosted-zones \ --region=${ REGION } \ | jq -r ".HostedZones[] | select(.Name == \" ${ SEARCH_KEY } \" ).Id" ) # ãã®åŸã®ç»é²ã³ãã³ãã§æå®ããããã®å®çŸ©ãã¡ã€ã« # æ¯èµ·åæã®ç»é²çšïŒIP ãå€ããããïŒã«ãAction ã«ã¯ 'UPSERT' ãæå® RECORDSET_FILE = "/tmp/create_recordset.json" cat << EOT > ${ RECORDSET_FILE } { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "<ã¯ã©ã€ã¢ã³ãèå¥ ID>.local", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "${ PRIVATE_IP }" } ] } } ] } EOT # äœæããå®çŸ©ãã¡ã€ã«ãæå®ããRoute53 ã«ç»é² aws route53 change-resource-record-sets \ --hosted-zone-id ${ HOSTED_ZONE_ID } \ --change-batch file:/// ${ RECORDSET_FILE } å®è¡ããã¹ãããã¯ããå€ãã§ããããã®ãããªæ§æããšãããšã§ VPC å
ã§ã¯ãã¡ã€ã³æå®ã§ã®ã¢ã¯ã»ã¹ãå¯èœãšãªããããIP ãæèããå¿
èŠããªããªãããæè»ãªæ§æã«ãªãããšæããŸãã ä»åã®ãŸãšã ããŸããã€ã³ã¹ã¿ã³ã¹ç«ãŠããšãããã©ããããªãããããšãæããªããè²ã
調ã¹ãŠæ§ç¯ããŸããããEC2 ãŸããã®ãµãŒãã¹ãå¢ããŠããã ãªãããªããŠæããŸããïŒç¹ã«ãã©ã¡ãŒã¿ã¹ãã¢ã¯ãšãŠã䟿å©ïŒ ãã©ã¡ãŒã¿ã¹ãã¢ä»¥å€ã«ã Systems Manager ã«ã¯ Run Command ã Patch Manager ãªã© EC2 ã€ã³ã¹ã¿ã³ã¹ã管çããäžã§ãšãŠã䟿å©ãªä»çµã¿ãæã£ãŠããŸãã®ã§ãã®ããããå°å
¥ããŠãããããšæããŸãã äœè«ã§ãããSystems Manager ã®ååšã¯ re:Invent 2016 ã§çºè¡šãããæããååã ãã¯ç¥ã£ãŠãŸããããä»åã®å¯Ÿå¿ãããŸã§ãã£ãšãªã³ãã¬å°çšã®ãµãŒãã¹ã ãšåéãããŠãŠèšæ¶ããæ¶ããããŠããŸããããã æåŸã« åç·šã Proxy å±€ ïŒNginxïŒãåŸç·šã App å±€ïŒEC2ïŒã«ã€ããŠæžãããŠããã ããŸããããããã ã£ãã§ããããã ããããã®èŠä»¶èªäœããã£ããç¹æ®ã ã£ãããããã®ã§ããªãã§ãããªæ§æã«ïŒã¿ãããªãšããããããç¥ããŸããããã©ãªããã®åèã«ãªãã°å¹žãã§ããããå°ãèããŠã¿ããããšãããã㯠wantedly ã®ã 話ãèããŠã¿ãã ããã¿ã³ããã©ããã â»åç·šããããããŠèªã¿ããæ¹ã¯ãã¡ãããã©ãã https://developer.medley.jp/entry/2017/08/24/120000_01 ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãããããšã§èŠåŽããç¹ãããïŒ åç·šåç
§ ïŒãå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãã åç·šã§ã¯ Proxy å±€ã®æ§æãšããŠã䞻㫠Nginx ã䜿çšãã Path Based Routing åšãã«ã€ããŠã®ã話ã§ãããåŸç·šã§ã¯ App å±€ã§äœ¿çšãã EC2ã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æããããŸãã App å±€ã®æ§æ App å±€ã®æ¹éãæ§ç¯ã®æµãçããŸãšãããšä»¥äžã®éãã§ãã ãŽãŒã«ãã³ã€ã¡ãŒãžãšã㊠OS èšå®ããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ãã imageïŒAMIïŒãäœæããŠãã äžèšã® AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãæ¯ã« EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãã ã€ã³ã¹ã¿ã³ã¹äœææã«å¿
èŠãª Tag ã®å€ãç°å¢å€æ°ãèšå®ããŠãã ç°å¢å€æ°ã¯ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² EC2 ã€ã³ã¹ã¿ã³ã¹èµ·åæã«ãã¯ã©ã€ã¢ã³ãã«å¿ãã Tag ãç°å¢å€æ°ãããšã«ãµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãããè¡ã èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ããã§ã¯ãããããã®è©³çްã«ã€ããŠèª¬æããŠãããããšæããŸãã AMI äœæ Packer ã䜿çšããŠåã€ã³ã¹ã¿ã³ã¹å
±éãšãªã AMI ãäœæããŸãã provisioners ã§æå®ããæ§ç¯çšã¹ã¯ãªããã§ OS èšå®ãå¿
èŠã©ã€ãã©ãªããŸãã¡ã€ã³ãšãªããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããŸãããŸããcloud-init ã䜿çšããŠååèµ·åæã«åããã¹ã¯ãªããé¡ãã³ããŒããŠãããŸãã ãªããcloud-init ããå®è¡ããã¹ã¯ãªãã㯠Git ã S3 ãªã©ããåçã«ååŸããæ¹æ³ããããŸããããã»ã©ã¹ã¯ãªããã®å
容ã«å€æŽã¯çºçããªãç¹ãšãå
容çã«å€æŽããå Žå㯠image åäœæãã©ã¡ãã«ããŠãå¿
èŠã«ãªãããã ã£ãã®ã§å²ãåã£ãŠ image å
ã«å«ããããšã«ããŠããŸãã äœæãã packer.json ã® provisioners éšåãæç²ãããšãã®ãããªæãã«ãªããŸãïŒèª¬æã³ã¡ã³ãéšåã¯å®éã«ã¯èšèŒããŠããŸããïŒ "provisioners" : [ -- type: shell ãšããŠãæ§ç¯çšã¹ã¯ãªããæå®ããã«ãæã«å®è¡ããã { "type" : "shell" , "scripts" : [ "scripts/provision.sh" ] }, -- type: file ã§ã€ã³ã¹ã¿ã³ã¹èµ·åæã«å®è¡ãããã¹ã¯ãªãã矀ãã³ã㌠-- ãããã®ã¹ã¯ãªãã㯠cloud-init ããå®è¡ãããïŒcloud-init ã®èšå®ã¯å¥éã€ã³ã¹ã¿ã³ã¹äœææã«è¡ã£ãŠããïŒ { "type" : "file" , "source" : "./scripts" , "destination" : "/home/hoge" }, -- äžèšã®ã¹ã¯ãªããã«å¯ŸããŠå®è¡æš©éä»äž { "type" : "shell" , "inline" : [ "chmod +x /home/hoge/scripts/*" ] } ] packer build ã§ãã«ããã image ã AWS ã«ä»åã®å
±éã§äœ¿çšãã AMI ãšããŠç»é²ãããŸã EC2 ã€ã³ã¹ã¿ã³ã¹äœæ äœæãã AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãããšã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãããªããã€ã³ã¹ã¿ã³ã¹äœæã¯ Terraform ã CloudFormation ãªã©ã¯äœ¿ãããAWS CLI ãå©çšããã¹ã¯ãªãããäœæããŠå®è¡ããŠããŸãã ã€ã³ã¹ã¿ã³ã¹äœæã¹ã¯ãªããã¯ãã®ãããªæµãã®åŠçãšãªããŸãã åŒæ°ã§ã¯ã©ã€ã¢ã³ãèå¥ ID ããã®ä»ãµãŒãã¢ããªã±ãŒã·ã§ã³ã»ããã¢ããã«å¿
èŠãšãªãç°å¢å€æ°ãæå® AWS CLI ã§ EC2 ã€ã³ã¹ã¿ã³ã¹äœæ åŒæ°ã§æå®ãããç°å¢å€æ°ã AWS CLI ã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² ã€ã³ã¹ã¿ã³ã¹äœæ 以äžã®ããã«ã aws ec2 run-instances ã³ãã³ãã䜿çšããTag ã«ã¯ã©ã€ã¢ã³ãèå¥ ID ãæå®ããŠäœæããŠããŸãã ããã§æå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«ãã©ã¡ãŒã¿ã¹ãã¢ããèªåçšã®ç°å¢å€æ°ãç»é²/ååŸããããPrivate DNS çšã®ãã¡ã€ã³ã«äœ¿çšããŸãã aws ec2 run-instances \ --image-id ${ AMI_ID } \ --key-name ${ KEY_NAME } --region ${ REGION } \ --subnet-id ${ SUBNET_ID } \ --security-group-ids ${ SECURITY_GROUP } \ --user-data file:// ${ USER_DATA } \ --instance-type ${ INSTANCE_TYPE } \ --tag-specifications "ResourceType=instance,Tags=[{Key=ClientId,Value=${ CLIENT_ID }}]" \ --iam-instance-profile "Arn=${ SERVICE_ROLE }" user-data ã«ã¯ååèµ·åæã«å®è¡ãããã¹ã¯ãªããïŒPacker ã§ãã«ãæã«ã³ããŒããŠãããã¹ã¯ãªããïŒãæå®ããŠããã ããšãªããŸãã #!/bin/bash /home/hoge/scripts/bootstrap.sh ãã©ã¡ãŒã¿ã¹ãã¢ã«ç°å¢å€æ°ç»é² 䜿çšããç°å¢å€æ°ã¯ãKey ã¯å
±éã§ããå€ãã¯ã©ã€ã¢ã³ãã«ãã£ãŠç°ãªããŸãããã®ãããHOGE ãšãã Key ã䜿çšããå Žåã <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é²ããŠããŸãã ïŒæ³š. ãã©ã¡ãŒã¿ã¹ãã¢ã« éå±€ãã¿ã°ä»ãããµããŒãããã ãããããã®ãããã®æ§æã¯ä»åŸèŠçŽãäºå®ã§ãïŒ ç»é²ã¯ aws ssm put-parameter ãå®è¡ããŸã aws ssm put-parameter \ --name ${ KEY } \ --value ${ VALUE } \ --type ${ PARAMETER_TYPE } \ # StringãSecureString ãªã© --overwrite ããã§ã¯ã©ã€ã¢ã³ãããšã® EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãèµ·åãããŸããæ¬¡ã«ã€ã³ã¹ã¿ã³ã¹èµ·åæã®æµãã«ã€ããŠã§ãã EC2 ã€ã³ã¹ã¿ã³ã¹èµ·å èµ·åæã¯ãååèµ·åãšæ¯åèµ·åã§ãããã以äžã®ãããªåŠçãè¡ããŸãã åå: ãã©ã¡ãŒã¿ã¹ãã¢ããèªèº«ã«é¢é£ããç°å¢å€æ°ãååŸãããµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãã æ¯å: èªèº«ã®å
éš IP ã Route53 ã® Private DNS ã«ç»é²/æŽæ° å
éš IP ã¯åºå®ããŠãããèµ·åæã«å²ãæ¯ããããããæ¯åæŽæ°ããããã«ããŠããŸãã ããã§ã¯ããããã®å
容ã«ã€ããŠèŠãŠãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ããç°å¢å€æ°ååŸ ç»é²æã®å
容ã§èšèŒããŸããããç°å¢å€æ°ã¯ <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ç»é²ããŠããŸãããã®ããããŸãã¯èªèº«ã®ã¯ã©ã€ã¢ã³ãèå¥ ID ãå€å®ããåŸã«å¿
èŠãªç°å¢å€æ°ã aws ssm get-parameters ã§ååŸããŸãã # èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãã¡ã¿ããŒã¿ããååŸ INSTANCE_ID =$( curl -s https://169.254.169.254/latest/meta-data/instance-id ) # ã¯ã©ã€ã¢ã³ãèå¥ ID ãã€ã³ã¹ã¿ã³ã¹äœææã«æå®ãã Tag ããååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) CLIENT_ID_TAG =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].Tags[] | select(.Key == "ClientId").Value' ) # ç°å¢å€æ°ãååŸ # ã¿ã€ãã SecureString ã«ããŠãã倿°ããããããäžåŸ --with-decryption ãªãã·ã§ã³ãæå®ããŠãã HOGE =$( aws ssm get-parameters \ --name "${ CLIENT_ID_TAG }.HOGE" \ --with-decryption --region ${ REGION } \ | jq -r ".Parameters[].Value" ) export HOGE =${ HOGE } å
éš IP ã Private DNS ã«ç»é² æåŸã«ãProxy å±€ãã Private DNS ã§åå解決ã§ããããã«èªèº«ã® IP ã Route 53 ã«ç»é²ããŠãããŸãã ãªããRoute53 ã«ã¯äºåã«å¯Ÿè±¡ã® Hosted Zone ã Private Hosted Zone for Amazon VPC ã¿ã€ããšããŠç»é²ããŠãããŸããããã§ã¯äŸãšã㊠Domain Name ã local ãšããŸãã EC2 ã€ã³ã¹ã¿ã³ã¹ããç»é²ããã RecordSet ã¯ä»¥äžã®åœ¢åŒãšããŸãã Name: <ã¯ã©ã€ã¢ã³ãèå¥ ID>.local Type: CNAME Value: EC2 ã€ã³ã¹ã¿ã³ã¹ã®å
éš IP ããããè¡ãã¹ã¯ãªããäŸã¯ä»¥äžãšãªããŸãã # å
éš IP ãååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) PRIVATE_IP =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].PrivateIpAddress' ) # Route53 ã®ç»é²å
Hosted Zone ID ãååŸ # SEARCH_KEY ã¯ä»åã®äŸã§ãããš 'local.' ã«ãªããŸã HOSTED_ZONE_ID =$( aws route53 list-hosted-zones \ --region=${ REGION } \ | jq -r ".HostedZones[] | select(.Name == \" ${ SEARCH_KEY } \" ).Id" ) # ãã®åŸã®ç»é²ã³ãã³ãã§æå®ããããã®å®çŸ©ãã¡ã€ã« # æ¯èµ·åæã®ç»é²çšïŒIP ãå€ããããïŒã«ãAction ã«ã¯ 'UPSERT' ãæå® RECORDSET_FILE = "/tmp/create_recordset.json" cat << EOT > ${ RECORDSET_FILE } { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "<ã¯ã©ã€ã¢ã³ãèå¥ ID>.local", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "${ PRIVATE_IP }" } ] } } ] } EOT # äœæããå®çŸ©ãã¡ã€ã«ãæå®ããRoute53 ã«ç»é² aws route53 change-resource-record-sets \ --hosted-zone-id ${ HOSTED_ZONE_ID } \ --change-batch file:/// ${ RECORDSET_FILE } å®è¡ããã¹ãããã¯ããå€ãã§ããããã®ãããªæ§æããšãããšã§ VPC å
ã§ã¯ãã¡ã€ã³æå®ã§ã®ã¢ã¯ã»ã¹ãå¯èœãšãªããããIP ãæèããå¿
èŠããªããªãããæè»ãªæ§æã«ãªãããšæããŸãã ä»åã®ãŸãšã ããŸããã€ã³ã¹ã¿ã³ã¹ç«ãŠããšãããã©ããããªãããããšãæããªããè²ã
調ã¹ãŠæ§ç¯ããŸããããEC2 ãŸããã®ãµãŒãã¹ãå¢ããŠããã ãªãããªããŠæããŸããïŒç¹ã«ãã©ã¡ãŒã¿ã¹ãã¢ã¯ãšãŠã䟿å©ïŒ ãã©ã¡ãŒã¿ã¹ãã¢ä»¥å€ã«ã Systems Manager ã«ã¯ Run Command ã Patch Manager ãªã© EC2 ã€ã³ã¹ã¿ã³ã¹ã管çããäžã§ãšãŠã䟿å©ãªä»çµã¿ãæã£ãŠããŸãã®ã§ãã®ããããå°å
¥ããŠãããããšæããŸãã äœè«ã§ãããSystems Manager ã®ååšã¯ re:Invent 2016 ã§çºè¡šãããæããååã ãã¯ç¥ã£ãŠãŸããããä»åã®å¯Ÿå¿ãããŸã§ãã£ãšãªã³ãã¬å°çšã®ãµãŒãã¹ã ãšåéãããŠãŠèšæ¶ããæ¶ããããŠããŸããããã æåŸã« åç·šã Proxy å±€ ïŒNginxïŒãåŸç·šã App å±€ïŒEC2ïŒã«ã€ããŠæžãããŠããã ããŸããããããã ã£ãã§ããããã ããããã®èŠä»¶èªäœããã£ããç¹æ®ã ã£ãããããã®ã§ããªãã§ãããªæ§æã«ïŒã¿ãããªãšããããããç¥ããŸããããã©ãªããã®åèã«ãªãã°å¹žãã§ããããå°ãèããŠã¿ããããšãããã㯠wantedly ã®ã 話ãèããŠã¿ãã ããã¿ã³ããã©ããã â»åç·šããããããŠèªã¿ããæ¹ã¯ãã¡ãããã©ãã https://developer.medley.jp/entry/2017/08/24/120000_01 ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãããããšã§èŠåŽããç¹ãããïŒ åç·šåç
§ ïŒãå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãã åç·šã§ã¯ Proxy å±€ã®æ§æãšããŠã䞻㫠Nginx ã䜿çšãã Path Based Routing åšãã«ã€ããŠã®ã話ã§ãããåŸç·šã§ã¯ App å±€ã§äœ¿çšãã EC2ã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æããããŸãã App å±€ã®æ§æ App å±€ã®æ¹éãæ§ç¯ã®æµãçããŸãšãããšä»¥äžã®éãã§ãã ãŽãŒã«ãã³ã€ã¡ãŒãžãšã㊠OS èšå®ããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ãã imageïŒAMIïŒãäœæããŠãã äžèšã® AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãæ¯ã« EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãã ã€ã³ã¹ã¿ã³ã¹äœææã«å¿
èŠãª Tag ã®å€ãç°å¢å€æ°ãèšå®ããŠãã ç°å¢å€æ°ã¯ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² EC2 ã€ã³ã¹ã¿ã³ã¹èµ·åæã«ãã¯ã©ã€ã¢ã³ãã«å¿ãã Tag ãç°å¢å€æ°ãããšã«ãµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãããè¡ã èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ããã§ã¯ãããããã®è©³çްã«ã€ããŠèª¬æããŠãããããšæããŸãã AMI äœæ Packer ã䜿çšããŠåã€ã³ã¹ã¿ã³ã¹å
±éãšãªã AMI ãäœæããŸãã provisioners ã§æå®ããæ§ç¯çšã¹ã¯ãªããã§ OS èšå®ãå¿
èŠã©ã€ãã©ãªããŸãã¡ã€ã³ãšãªããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããŸãããŸããcloud-init ã䜿çšããŠååèµ·åæã«åããã¹ã¯ãªããé¡ãã³ããŒããŠãããŸãã ãªããcloud-init ããå®è¡ããã¹ã¯ãªãã㯠Git ã S3 ãªã©ããåçã«ååŸããæ¹æ³ããããŸããããã»ã©ã¹ã¯ãªããã®å
容ã«å€æŽã¯çºçããªãç¹ãšãå
容çã«å€æŽããå Žå㯠image åäœæãã©ã¡ãã«ããŠãå¿
èŠã«ãªãããã ã£ãã®ã§å²ãåã£ãŠ image å
ã«å«ããããšã«ããŠããŸãã äœæãã packer.json ã® provisioners éšåãæç²ãããšãã®ãããªæãã«ãªããŸãïŒèª¬æã³ã¡ã³ãéšåã¯å®éã«ã¯èšèŒããŠããŸããïŒ "provisioners" : [ -- type: shell ãšããŠãæ§ç¯çšã¹ã¯ãªããæå®ããã«ãæã«å®è¡ããã { "type" : "shell" , "scripts" : [ "scripts/provision.sh" ] }, -- type: file ã§ã€ã³ã¹ã¿ã³ã¹èµ·åæã«å®è¡ãããã¹ã¯ãªãã矀ãã³ã㌠-- ãããã®ã¹ã¯ãªãã㯠cloud-init ããå®è¡ãããïŒcloud-init ã®èšå®ã¯å¥éã€ã³ã¹ã¿ã³ã¹äœææã«è¡ã£ãŠããïŒ { "type" : "file" , "source" : "./scripts" , "destination" : "/home/hoge" }, -- äžèšã®ã¹ã¯ãªããã«å¯ŸããŠå®è¡æš©éä»äž { "type" : "shell" , "inline" : [ "chmod +x /home/hoge/scripts/*" ] } ] packer build ã§ãã«ããã image ã AWS ã«ä»åã®å
±éã§äœ¿çšãã AMI ãšããŠç»é²ãããŸã EC2 ã€ã³ã¹ã¿ã³ã¹äœæ äœæãã AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãããšã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãããªããã€ã³ã¹ã¿ã³ã¹äœæã¯ Terraform ã CloudFormation ãªã©ã¯äœ¿ãããAWS CLI ãå©çšããã¹ã¯ãªãããäœæããŠå®è¡ããŠããŸãã ã€ã³ã¹ã¿ã³ã¹äœæã¹ã¯ãªããã¯ãã®ãããªæµãã®åŠçãšãªããŸãã åŒæ°ã§ã¯ã©ã€ã¢ã³ãèå¥ ID ããã®ä»ãµãŒãã¢ããªã±ãŒã·ã§ã³ã»ããã¢ããã«å¿
èŠãšãªãç°å¢å€æ°ãæå® AWS CLI ã§ EC2 ã€ã³ã¹ã¿ã³ã¹äœæ åŒæ°ã§æå®ãããç°å¢å€æ°ã AWS CLI ã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² ã€ã³ã¹ã¿ã³ã¹äœæ 以äžã®ããã«ã aws ec2 run-instances ã³ãã³ãã䜿çšããTag ã«ã¯ã©ã€ã¢ã³ãèå¥ ID ãæå®ããŠäœæããŠããŸãã ããã§æå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«ãã©ã¡ãŒã¿ã¹ãã¢ããèªåçšã®ç°å¢å€æ°ãç»é²/ååŸããããPrivate DNS çšã®ãã¡ã€ã³ã«äœ¿çšããŸãã aws ec2 run-instances \ --image-id ${ AMI_ID } \ --key-name ${ KEY_NAME } --region ${ REGION } \ --subnet-id ${ SUBNET_ID } \ --security-group-ids ${ SECURITY_GROUP } \ --user-data file:// ${ USER_DATA } \ --instance-type ${ INSTANCE_TYPE } \ --tag-specifications "ResourceType=instance,Tags=[{Key=ClientId,Value=${ CLIENT_ID }}]" \ --iam-instance-profile "Arn=${ SERVICE_ROLE }" user-data ã«ã¯ååèµ·åæã«å®è¡ãããã¹ã¯ãªããïŒPacker ã§ãã«ãæã«ã³ããŒããŠãããã¹ã¯ãªããïŒãæå®ããŠããã ããšãªããŸãã #!/bin/bash /home/hoge/scripts/bootstrap.sh ãã©ã¡ãŒã¿ã¹ãã¢ã«ç°å¢å€æ°ç»é² 䜿çšããç°å¢å€æ°ã¯ãKey ã¯å
±éã§ããå€ãã¯ã©ã€ã¢ã³ãã«ãã£ãŠç°ãªããŸãããã®ãããHOGE ãšãã Key ã䜿çšããå Žåã <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é²ããŠããŸãã ïŒæ³š. ãã©ã¡ãŒã¿ã¹ãã¢ã« éå±€ãã¿ã°ä»ãããµããŒãããã ãããããã®ãããã®æ§æã¯ä»åŸèŠçŽãäºå®ã§ãïŒ ç»é²ã¯ aws ssm put-parameter ãå®è¡ããŸã aws ssm put-parameter \ --name ${ KEY } \ --value ${ VALUE } \ --type ${ PARAMETER_TYPE } \ # StringãSecureString ãªã© --overwrite ããã§ã¯ã©ã€ã¢ã³ãããšã® EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãèµ·åãããŸããæ¬¡ã«ã€ã³ã¹ã¿ã³ã¹èµ·åæã®æµãã«ã€ããŠã§ãã EC2 ã€ã³ã¹ã¿ã³ã¹èµ·å èµ·åæã¯ãååèµ·åãšæ¯åèµ·åã§ãããã以äžã®ãããªåŠçãè¡ããŸãã åå: ãã©ã¡ãŒã¿ã¹ãã¢ããèªèº«ã«é¢é£ããç°å¢å€æ°ãååŸãããµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãã æ¯å: èªèº«ã®å
éš IP ã Route53 ã® Private DNS ã«ç»é²/æŽæ° å
éš IP ã¯åºå®ããŠãããèµ·åæã«å²ãæ¯ããããããæ¯åæŽæ°ããããã«ããŠããŸãã ããã§ã¯ããããã®å
容ã«ã€ããŠèŠãŠãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ããç°å¢å€æ°ååŸ ç»é²æã®å
容ã§èšèŒããŸããããç°å¢å€æ°ã¯ <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ç»é²ããŠããŸãããã®ããããŸãã¯èªèº«ã®ã¯ã©ã€ã¢ã³ãèå¥ ID ãå€å®ããåŸã«å¿
èŠãªç°å¢å€æ°ã aws ssm get-parameters ã§ååŸããŸãã # èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãã¡ã¿ããŒã¿ããååŸ INSTANCE_ID =$( curl -s https://169.254.169.254/latest/meta-data/instance-id ) # ã¯ã©ã€ã¢ã³ãèå¥ ID ãã€ã³ã¹ã¿ã³ã¹äœææã«æå®ãã Tag ããååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) CLIENT_ID_TAG =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].Tags[] | select(.Key == "ClientId").Value' ) # ç°å¢å€æ°ãååŸ # ã¿ã€ãã SecureString ã«ããŠãã倿°ããããããäžåŸ --with-decryption ãªãã·ã§ã³ãæå®ããŠãã HOGE =$( aws ssm get-parameters \ --name "${ CLIENT_ID_TAG }.HOGE" \ --with-decryption --region ${ REGION } \ | jq -r ".Parameters[].Value" ) export HOGE =${ HOGE } å
éš IP ã Private DNS ã«ç»é² æåŸã«ãProxy å±€ãã Private DNS ã§åå解決ã§ããããã«èªèº«ã® IP ã Route 53 ã«ç»é²ããŠãããŸãã ãªããRoute53 ã«ã¯äºåã«å¯Ÿè±¡ã® Hosted Zone ã Private Hosted Zone for Amazon VPC ã¿ã€ããšããŠç»é²ããŠãããŸããããã§ã¯äŸãšã㊠Domain Name ã local ãšããŸãã EC2 ã€ã³ã¹ã¿ã³ã¹ããç»é²ããã RecordSet ã¯ä»¥äžã®åœ¢åŒãšããŸãã Name: <ã¯ã©ã€ã¢ã³ãèå¥ ID>.local Type: CNAME Value: EC2 ã€ã³ã¹ã¿ã³ã¹ã®å
éš IP ããããè¡ãã¹ã¯ãªããäŸã¯ä»¥äžãšãªããŸãã # å
éš IP ãååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) PRIVATE_IP =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].PrivateIpAddress' ) # Route53 ã®ç»é²å
Hosted Zone ID ãååŸ # SEARCH_KEY ã¯ä»åã®äŸã§ãããš 'local.' ã«ãªããŸã HOSTED_ZONE_ID =$( aws route53 list-hosted-zones \ --region=${ REGION } \ | jq -r ".HostedZones[] | select(.Name == \" ${ SEARCH_KEY } \" ).Id" ) # ãã®åŸã®ç»é²ã³ãã³ãã§æå®ããããã®å®çŸ©ãã¡ã€ã« # æ¯èµ·åæã®ç»é²çšïŒIP ãå€ããããïŒã«ãAction ã«ã¯ 'UPSERT' ãæå® RECORDSET_FILE = "/tmp/create_recordset.json" cat << EOT > ${ RECORDSET_FILE } { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "<ã¯ã©ã€ã¢ã³ãèå¥ ID>.local", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "${ PRIVATE_IP }" } ] } } ] } EOT # äœæããå®çŸ©ãã¡ã€ã«ãæå®ããRoute53 ã«ç»é² aws route53 change-resource-record-sets \ --hosted-zone-id ${ HOSTED_ZONE_ID } \ --change-batch file:/// ${ RECORDSET_FILE } å®è¡ããã¹ãããã¯ããå€ãã§ããããã®ãããªæ§æããšãããšã§ VPC å
ã§ã¯ãã¡ã€ã³æå®ã§ã®ã¢ã¯ã»ã¹ãå¯èœãšãªããããIP ãæèããå¿
èŠããªããªãããæè»ãªæ§æã«ãªãããšæããŸãã ä»åã®ãŸãšã ããŸããã€ã³ã¹ã¿ã³ã¹ç«ãŠããšãããã©ããããªãããããšãæããªããè²ã
調ã¹ãŠæ§ç¯ããŸããããEC2 ãŸããã®ãµãŒãã¹ãå¢ããŠããã ãªãããªããŠæããŸããïŒç¹ã«ãã©ã¡ãŒã¿ã¹ãã¢ã¯ãšãŠã䟿å©ïŒ ãã©ã¡ãŒã¿ã¹ãã¢ä»¥å€ã«ã Systems Manager ã«ã¯ Run Command ã Patch Manager ãªã© EC2 ã€ã³ã¹ã¿ã³ã¹ã管çããäžã§ãšãŠã䟿å©ãªä»çµã¿ãæã£ãŠããŸãã®ã§ãã®ããããå°å
¥ããŠãããããšæããŸãã äœè«ã§ãããSystems Manager ã®ååšã¯ re:Invent 2016 ã§çºè¡šãããæããååã ãã¯ç¥ã£ãŠãŸããããä»åã®å¯Ÿå¿ãããŸã§ãã£ãšãªã³ãã¬å°çšã®ãµãŒãã¹ã ãšåéãããŠãŠèšæ¶ããæ¶ããããŠããŸããããã æåŸã« åç·šã Proxy å±€ ïŒNginxïŒãåŸç·šã App å±€ïŒEC2ïŒã«ã€ããŠæžãããŠããã ããŸããããããã ã£ãã§ããããã ããããã®èŠä»¶èªäœããã£ããç¹æ®ã ã£ãããããã®ã§ããªãã§ãããªæ§æã«ïŒã¿ãããªãšããããããç¥ããŸããããã©ãªããã®åèã«ãªãã°å¹žãã§ããããå°ãèããŠã¿ããããšãããã㯠wantedly ã®ã 話ãèããŠã¿ãã ããã¿ã³ããã©ããã â»åç·šããããããŠèªã¿ããæ¹ã¯ãã¡ãããã©ãã https://developer.medley.jp/entry/2017/08/24/120000_01 ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãããããšã§èŠåŽããç¹ãããïŒ åç·šåç
§ ïŒãå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãã åç·šã§ã¯ Proxy å±€ã®æ§æãšããŠã䞻㫠Nginx ã䜿çšãã Path Based Routing åšãã«ã€ããŠã®ã話ã§ãããåŸç·šã§ã¯ App å±€ã§äœ¿çšãã EC2ã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æããããŸãã App å±€ã®æ§æ App å±€ã®æ¹éãæ§ç¯ã®æµãçããŸãšãããšä»¥äžã®éãã§ãã ãŽãŒã«ãã³ã€ã¡ãŒãžãšã㊠OS èšå®ããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ãã imageïŒAMIïŒãäœæããŠãã äžèšã® AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãæ¯ã« EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãã ã€ã³ã¹ã¿ã³ã¹äœææã«å¿
èŠãª Tag ã®å€ãç°å¢å€æ°ãèšå®ããŠãã ç°å¢å€æ°ã¯ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² EC2 ã€ã³ã¹ã¿ã³ã¹èµ·åæã«ãã¯ã©ã€ã¢ã³ãã«å¿ãã Tag ãç°å¢å€æ°ãããšã«ãµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãããè¡ã èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ããã§ã¯ãããããã®è©³çްã«ã€ããŠèª¬æããŠãããããšæããŸãã AMI äœæ Packer ã䜿çšããŠåã€ã³ã¹ã¿ã³ã¹å
±éãšãªã AMI ãäœæããŸãã provisioners ã§æå®ããæ§ç¯çšã¹ã¯ãªããã§ OS èšå®ãå¿
èŠã©ã€ãã©ãªããŸãã¡ã€ã³ãšãªããµãŒãã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããŸãããŸããcloud-init ã䜿çšããŠååèµ·åæã«åããã¹ã¯ãªããé¡ãã³ããŒããŠãããŸãã ãªããcloud-init ããå®è¡ããã¹ã¯ãªãã㯠Git ã S3 ãªã©ããåçã«ååŸããæ¹æ³ããããŸããããã»ã©ã¹ã¯ãªããã®å
容ã«å€æŽã¯çºçããªãç¹ãšãå
容çã«å€æŽããå Žå㯠image åäœæãã©ã¡ãã«ããŠãå¿
èŠã«ãªãããã ã£ãã®ã§å²ãåã£ãŠ image å
ã«å«ããããšã«ããŠããŸãã äœæãã packer.json ã® provisioners éšåãæç²ãããšãã®ãããªæãã«ãªããŸãïŒèª¬æã³ã¡ã³ãéšåã¯å®éã«ã¯èšèŒããŠããŸããïŒ "provisioners" : [ -- type: shell ãšããŠãæ§ç¯çšã¹ã¯ãªããæå®ããã«ãæã«å®è¡ããã { "type" : "shell" , "scripts" : [ "scripts/provision.sh" ] }, -- type: file ã§ã€ã³ã¹ã¿ã³ã¹èµ·åæã«å®è¡ãããã¹ã¯ãªãã矀ãã³ã㌠-- ãããã®ã¹ã¯ãªãã㯠cloud-init ããå®è¡ãããïŒcloud-init ã®èšå®ã¯å¥éã€ã³ã¹ã¿ã³ã¹äœææã«è¡ã£ãŠããïŒ { "type" : "file" , "source" : "./scripts" , "destination" : "/home/hoge" }, -- äžèšã®ã¹ã¯ãªããã«å¯ŸããŠå®è¡æš©éä»äž { "type" : "shell" , "inline" : [ "chmod +x /home/hoge/scripts/*" ] } ] packer build ã§ãã«ããã image ã AWS ã«ä»åã®å
±éã§äœ¿çšãã AMI ãšããŠç»é²ãããŸã EC2 ã€ã³ã¹ã¿ã³ã¹äœæ äœæãã AMI ãå
ã«ãã¯ã©ã€ã¢ã³ãããšã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãããªããã€ã³ã¹ã¿ã³ã¹äœæã¯ Terraform ã CloudFormation ãªã©ã¯äœ¿ãããAWS CLI ãå©çšããã¹ã¯ãªãããäœæããŠå®è¡ããŠããŸãã ã€ã³ã¹ã¿ã³ã¹äœæã¹ã¯ãªããã¯ãã®ãããªæµãã®åŠçãšãªããŸãã åŒæ°ã§ã¯ã©ã€ã¢ã³ãèå¥ ID ããã®ä»ãµãŒãã¢ããªã±ãŒã·ã§ã³ã»ããã¢ããã«å¿
èŠãšãªãç°å¢å€æ°ãæå® AWS CLI ã§ EC2 ã€ã³ã¹ã¿ã³ã¹äœæ åŒæ°ã§æå®ãããç°å¢å€æ°ã AWS CLI ã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é² ã€ã³ã¹ã¿ã³ã¹äœæ 以äžã®ããã«ã aws ec2 run-instances ã³ãã³ãã䜿çšããTag ã«ã¯ã©ã€ã¢ã³ãèå¥ ID ãæå®ããŠäœæããŠããŸãã ããã§æå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«ãã©ã¡ãŒã¿ã¹ãã¢ããèªåçšã®ç°å¢å€æ°ãç»é²/ååŸããããPrivate DNS çšã®ãã¡ã€ã³ã«äœ¿çšããŸãã aws ec2 run-instances \ --image-id ${ AMI_ID } \ --key-name ${ KEY_NAME } --region ${ REGION } \ --subnet-id ${ SUBNET_ID } \ --security-group-ids ${ SECURITY_GROUP } \ --user-data file:// ${ USER_DATA } \ --instance-type ${ INSTANCE_TYPE } \ --tag-specifications "ResourceType=instance,Tags=[{Key=ClientId,Value=${ CLIENT_ID }}]" \ --iam-instance-profile "Arn=${ SERVICE_ROLE }" user-data ã«ã¯ååèµ·åæã«å®è¡ãããã¹ã¯ãªããïŒPacker ã§ãã«ãæã«ã³ããŒããŠãããã¹ã¯ãªããïŒãæå®ããŠããã ããšãªããŸãã #!/bin/bash /home/hoge/scripts/bootstrap.sh ãã©ã¡ãŒã¿ã¹ãã¢ã«ç°å¢å€æ°ç»é² 䜿çšããç°å¢å€æ°ã¯ãKey ã¯å
±éã§ããå€ãã¯ã©ã€ã¢ã³ãã«ãã£ãŠç°ãªããŸãããã®ãããHOGE ãšãã Key ã䜿çšããå Žåã <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ãã©ã¡ãŒã¿ã¹ãã¢ã«ç»é²ããŠããŸãã ïŒæ³š. ãã©ã¡ãŒã¿ã¹ãã¢ã« éå±€ãã¿ã°ä»ãããµããŒãããã ãããããã®ãããã®æ§æã¯ä»åŸèŠçŽãäºå®ã§ãïŒ ç»é²ã¯ aws ssm put-parameter ãå®è¡ããŸã aws ssm put-parameter \ --name ${ KEY } \ --value ${ VALUE } \ --type ${ PARAMETER_TYPE } \ # StringãSecureString ãªã© --overwrite ããã§ã¯ã©ã€ã¢ã³ãããšã® EC2 ã€ã³ã¹ã¿ã³ã¹ãäœæãèµ·åãããŸããæ¬¡ã«ã€ã³ã¹ã¿ã³ã¹èµ·åæã®æµãã«ã€ããŠã§ãã EC2 ã€ã³ã¹ã¿ã³ã¹èµ·å èµ·åæã¯ãååèµ·åãšæ¯åèµ·åã§ãããã以äžã®ãããªåŠçãè¡ããŸãã åå: ãã©ã¡ãŒã¿ã¹ãã¢ããèªèº«ã«é¢é£ããç°å¢å€æ°ãååŸãããµãŒãã¢ããªã±ãŒã·ã§ã³ã®ã»ããã¢ãã æ¯å: èªèº«ã®å
éš IP ã Route53 ã® Private DNS ã«ç»é²/æŽæ° å
éš IP ã¯åºå®ããŠãããèµ·åæã«å²ãæ¯ããããããæ¯åæŽæ°ããããã«ããŠããŸãã ããã§ã¯ããããã®å
容ã«ã€ããŠèŠãŠãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ããç°å¢å€æ°ååŸ ç»é²æã®å
容ã§èšèŒããŸããããç°å¢å€æ°ã¯ <ã¯ã©ã€ã¢ã³ãèå¥ ID>.HOGE ãšãã圢åŒã§ç»é²ããŠããŸãããã®ããããŸãã¯èªèº«ã®ã¯ã©ã€ã¢ã³ãèå¥ ID ãå€å®ããåŸã«å¿
èŠãªç°å¢å€æ°ã aws ssm get-parameters ã§ååŸããŸãã # èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãã¡ã¿ããŒã¿ããååŸ INSTANCE_ID =$( curl -s https://169.254.169.254/latest/meta-data/instance-id ) # ã¯ã©ã€ã¢ã³ãèå¥ ID ãã€ã³ã¹ã¿ã³ã¹äœææã«æå®ãã Tag ããååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) CLIENT_ID_TAG =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].Tags[] | select(.Key == "ClientId").Value' ) # ç°å¢å€æ°ãååŸ # ã¿ã€ãã SecureString ã«ããŠãã倿°ããããããäžåŸ --with-decryption ãªãã·ã§ã³ãæå®ããŠãã HOGE =$( aws ssm get-parameters \ --name "${ CLIENT_ID_TAG }.HOGE" \ --with-decryption --region ${ REGION } \ | jq -r ".Parameters[].Value" ) export HOGE =${ HOGE } å
éš IP ã Private DNS ã«ç»é² æåŸã«ãProxy å±€ãã Private DNS ã§åå解決ã§ããããã«èªèº«ã® IP ã Route 53 ã«ç»é²ããŠãããŸãã ãªããRoute53 ã«ã¯äºåã«å¯Ÿè±¡ã® Hosted Zone ã Private Hosted Zone for Amazon VPC ã¿ã€ããšããŠç»é²ããŠãããŸããããã§ã¯äŸãšã㊠Domain Name ã local ãšããŸãã EC2 ã€ã³ã¹ã¿ã³ã¹ããç»é²ããã RecordSet ã¯ä»¥äžã®åœ¢åŒãšããŸãã Name: <ã¯ã©ã€ã¢ã³ãèå¥ ID>.local Type: CNAME Value: EC2 ã€ã³ã¹ã¿ã³ã¹ã®å
éš IP ããããè¡ãã¹ã¯ãªããäŸã¯ä»¥äžãšãªããŸãã # å
éš IP ãååŸ # (describe-instances ã® filter ã«èªèº«ã®ã€ã³ã¹ã¿ã³ã¹ ID ãæå®) PRIVATE_IP =$( aws ec2 describe-instances \ --region=${ REGION } \ --filters "Name=instance-id,Values=${ INSTANCE_ID }" \ | jq -r '.Reservations[].Instances[].PrivateIpAddress' ) # Route53 ã®ç»é²å
Hosted Zone ID ãååŸ # SEARCH_KEY ã¯ä»åã®äŸã§ãããš 'local.' ã«ãªããŸã HOSTED_ZONE_ID =$( aws route53 list-hosted-zones \ --region=${ REGION } \ | jq -r ".HostedZones[] | select(.Name == \" ${ SEARCH_KEY } \" ).Id" ) # ãã®åŸã®ç»é²ã³ãã³ãã§æå®ããããã®å®çŸ©ãã¡ã€ã« # æ¯èµ·åæã®ç»é²çšïŒIP ãå€ããããïŒã«ãAction ã«ã¯ 'UPSERT' ãæå® RECORDSET_FILE = "/tmp/create_recordset.json" cat << EOT > ${ RECORDSET_FILE } { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "<ã¯ã©ã€ã¢ã³ãèå¥ ID>.local", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "${ PRIVATE_IP }" } ] } } ] } EOT # äœæããå®çŸ©ãã¡ã€ã«ãæå®ããRoute53 ã«ç»é² aws route53 change-resource-record-sets \ --hosted-zone-id ${ HOSTED_ZONE_ID } \ --change-batch file:/// ${ RECORDSET_FILE } å®è¡ããã¹ãããã¯ããå€ãã§ããããã®ãããªæ§æããšãããšã§ VPC å
ã§ã¯ãã¡ã€ã³æå®ã§ã®ã¢ã¯ã»ã¹ãå¯èœãšãªããããIP ãæèããå¿
èŠããªããªãããæè»ãªæ§æã«ãªãããšæããŸãã ä»åã®ãŸãšã ããŸããã€ã³ã¹ã¿ã³ã¹ç«ãŠããšãããã©ããããªãããããšãæããªããè²ã
調ã¹ãŠæ§ç¯ããŸããããEC2 ãŸããã®ãµãŒãã¹ãå¢ããŠããã ãªãããªããŠæããŸããïŒç¹ã«ãã©ã¡ãŒã¿ã¹ãã¢ã¯ãšãŠã䟿å©ïŒ ãã©ã¡ãŒã¿ã¹ãã¢ä»¥å€ã«ã Systems Manager ã«ã¯ Run Command ã Patch Manager ãªã© EC2 ã€ã³ã¹ã¿ã³ã¹ã管çããäžã§ãšãŠã䟿å©ãªä»çµã¿ãæã£ãŠããŸãã®ã§ãã®ããããå°å
¥ããŠãããããšæããŸãã äœè«ã§ãããSystems Manager ã®ååšã¯ re:Invent 2016 ã§çºè¡šãããæããååã ãã¯ç¥ã£ãŠãŸããããä»åã®å¯Ÿå¿ãããŸã§ãã£ãšãªã³ãã¬å°çšã®ãµãŒãã¹ã ãšåéãããŠãŠèšæ¶ããæ¶ããããŠããŸããããã æåŸã« åç·šã Proxy å±€ ïŒNginxïŒãåŸç·šã App å±€ïŒEC2ïŒã«ã€ããŠæžãããŠããã ããŸããããããã ã£ãã§ããããã ããããã®èŠä»¶èªäœããã£ããç¹æ®ã ã£ãããããã®ã§ããªãã§ãããªæ§æã«ïŒã¿ãããªãšããããããç¥ããŸããããã©ãªããã®åèã«ãªãã°å¹žãã§ããããå°ãèããŠã¿ããããšãããã㯠wantedly ã®ã 話ãèããŠã¿ãã ããã¿ã³ããã©ããã â»åç·šããããããŠèªã¿ããæ¹ã¯ãã¡ãããã©ãã https://developer.medley.jp/entry/2017/08/24/120000_01 ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã ã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¿
èŠãªãµãŒãã AWS ã§æ§ç¯ïŒåŸç·šïŒApp å±€ïŒ | MEDLEY Developer Portal ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã®ç°äžã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãã... developer.medley.jp åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã Nginx balancer_by_luaã®è©±ãšupstreamåå解決ã®è©± - Qiita balancer_by_lua_xxxxx ãã€ã®éã«ãã1 lua-nginx-module ã« balancer_by_lua_xxx ãšããæ°ãããã£ã¬ã¯ãã£ããå¢ããŠããŸããã 以äžããã¥ã¡ã³ãããæç²ã http { upstream backend {... qiita.com ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã https://developer.medley.jp/entry/2017/08/24/120000_02 åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã https://qiita.com/toritori0318/items/a9305d528b52936c0573 ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã https://www.medley.jp/recruit/creative.html
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã ã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¿
èŠãªãµãŒãã AWS ã§æ§ç¯ïŒåŸç·šïŒApp å±€ïŒ | MEDLEY Developer Portal ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã®ç°äžã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãã... developer.medley.jp åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã Nginx balancer_by_luaã®è©±ãšupstreamåå解決ã®è©± - Qiita balancer_by_lua_xxxxxãã€ã®éã«ãã[^1] lua-nginx-module ã« balancer_by_lua_xxx ãšããæ°ãããã£ã¬ã¯ãã£ããå¢ããŠããŸããã以äžã⊠qiita.com ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã ã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¿
èŠãªãµãŒãã AWS ã§æ§ç¯ïŒåŸç·šïŒApp å±€ïŒ | MEDLEY Developer Portal ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã®ç°äžã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãã... developer.medley.jp åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã Nginx balancer_by_luaã®è©±ãšupstreamåå解決ã®è©± - Qiita balancer_by_lua_xxxxxãã€ã®éã«ãã[^1] lua-nginx-module ã« balancer_by_lua_xxx ãšããæ°ãããã£ã¬ã¯ãã£ããå¢ããŠããŸããã以äžã⊠qiita.com ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã ã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¿
èŠãªãµãŒãã AWS ã§æ§ç¯ïŒåŸç·šïŒApp å±€ïŒ | MEDLEY Developer Portal ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã®ç°äžã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãã... developer.medley.jp åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã Nginx balancer_by_luaã®è©±ãšupstreamåå解決ã®è©± - Qiita balancer_by_lua_xxxxx ãã€ã®éã«ãã1 lua-nginx-module ã« balancer_by_lua_xxx ãšããæ°ãããã£ã¬ã¯ãã£ããå¢ããŠããŸããã 以äžããã¥ã¡ã³ãããæç²ã http { upstream backend {... qiita.com ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã ã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¿
èŠãªãµãŒãã AWS ã§æ§ç¯ïŒåŸç·šïŒApp å±€ïŒ | MEDLEY Developer Portal ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã®ç°äžã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãã... developer.medley.jp åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã Nginx balancer_by_luaã®è©±ãšupstreamåå解決ã®è©± - Qiita balancer_by_lua_xxxxx ãã€ã®éã«ãã1 lua-nginx-module ã« balancer_by_lua_xxx ãšããæ°ãããã£ã¬ã¯ãã£ããå¢ããŠããŸããã 以äžããã¥ã¡ã³ãããæç²ã http { upstream backend {... qiita.com ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã ã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¿
èŠãªãµãŒãã AWS ã§æ§ç¯ïŒåŸç·šïŒApp å±€ïŒ | MEDLEY Developer Portal ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã®ç°äžã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãã... developer.medley.jp åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã Nginx balancer_by_luaã®è©±ãšupstreamåå解決ã®è©± - Qiita balancer_by_lua_xxxxx ãã€ã®éã«ãã1 lua-nginx-module ã« balancer_by_lua_xxx ãšããæ°ãããã£ã¬ã¯ãã£ããå¢ããŠããŸããã 以äžããã¥ã¡ã³ãããæç²ã http { upstream backend {... qiita.com ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã® ç°äž ã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããåŸè¿°ããå¶çŽããèŠåŽããç¹ããããå¶çŽãä¹ãè¶ããããã®å·¥å€«ãå«ããŠã話ã§ããéãå
±æãããŠããã ããŸãïŒå
ã«ãäŒãããŠãããšãç¹æ®ãªäºæ
ããªããã°ä»åã®ãããªã±ãŒã¹ã§ã¯ ALB ã§å¯Ÿå¿ãã ECS ãµãŒãã¹ã« Path Based Routing ããŠããã®ãè¯ããšæããŸãïŒã æè¡èŠçŽ ãšããŠãNginxïŒOpenRestyïŒ/ Route53 Private DNS / EC2 / Systems Manager ãã©ã¡ãŒã¿ã¹ã㢠ãããã«è§ŠããããšæããŸããïŒBeanstalk 㯠Multicontainer Docker ã䜿çšãããããæ
£ãããŸã§ã¡ãã£ãšã¯ã»ãã£ããªããšæã£ãã®ã§ããåéãå€ããªããããªã®ã§ãŸãå¥ã®æ©äŒã«å
±æãããŠé ããŸãïŒ ãŸãåç·šãšã㊠Proxy å±€ã䞻㫠Nginx ã䜿çšãã Dynamic Path Based Routing ã«ã€ããŠã話ããŠã åŸç·šã¯ App å±€ ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã èšèš/æ§ç¯ããäžã§ã®åæãšæ¹é 察象ãšãªãæ¡ä»¶ãé²ããäžã§ã®èŠä»¶ã»å¶éå
容ã¯è«žäºæ
ããããã£ãšãŸãšãããšãã®ãããªæãã§ãã ç°å¢ã¯ AWS ã䜿çšãã ãµãŒãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶æ¯ã§ããµãŒãã¢ããªã±ãŒã·ã§ã³ã¯å
±çšã§ããªãïŒãŠãŒã¶ãå¢ãã床ã«ã¯ã©ã€ã¢ã³ã/ãµãŒãã®ã»ãããå¢ããã€ã¡ãŒãžïŒ ãã ããã¯ã©ã€ã¢ã³ãããã®æ¥ç¶å
ãšãªã Endpoint ã¯åãã ããHost Based Routing ã¯èš³ãã£ãŠå©çšã§ããªã ã¯ã©ã€ã¢ã³ãèªèšŒã䜿çšãã äžèšããã以äžã®èšèšæ¹éã§é²ããäºã«ããŸããã Proxy å±€ã§ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ããPath Based Routing ã§å¯Ÿè±¡ãšãªããµãŒãã«ãªã¯ãšã¹ãã proxy ãããPath éšåã«ã¯ã©ã€ã¢ã³ãå¥ã®èå¥ ID ãå«ãããã®å€ãå
ã« Private DNS ã§åå解決ãã äŸ) https://example.com/a-client/api => https://a-client.local/api App å±€ã¯åå¥ EC2 ã€ã³ã¹ã¿ã³ã¹ãšãã èšèšããäžã§æ©ãã ç¹ äž»ã« 2 ç¹ãããŸããããŸã㯠Proxy å±€ã§ããåºæ¥ãã ã AWS ã®ãããŒãžãã»ãµãŒãã¹ã§æžãŸãããã£ãã®ã§ãã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¯èœã§ããããäºã«åããã©ãã調ã¹ãŸããã以äžã®çç±ã§æå¿µããæ®éïŒ?ïŒã« ELB + Nginx ãå©çšããããšã«ããŸããã ALB: ã¯ã©ã€ã¢ã³ãèªèšŒã«é察å¿ããŸã SSL çµç«¯ãšãªãã®ã§ Nginx åŽã§ã¯ã©ã€ã¢ã³ãèªèšŒãåºæ¥ãªã API GW: ã¯ã©ã€ã¢ã³ãèªèšŒã¯å¯Ÿå¿ããŠãã Routing éšåãããã°ãã°ãããããïŒããšæã£ãã Proxy å
ãåçã«å¢ãããªããã®ã§ç®¡çãµããé£ãããã§ãã£ã 次㫠App å±€ã®æ§æãã©ããããã§ãããéç©åºŠãé«ããããã«ã³ã³ããå©çšãæ€èšããã®ã§ããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®å¿
èŠã¹ããã¯ãèŠä»¶ãªã©ããããŸãã¡ãã£ãããããåå¥ã® EC2 ã€ã³ã¹ã¿ã³ã¹ã«ããããšã«ããŸããïŒä»ã§ããã£ãšè¯ãæ¹æ³ããªããæ©ãã§ããããŸãïŒ å
šäœæ§æ åºæ¥äžãã£ãå
šäœæ§æã®ã€ã¡ãŒãžã¯ä»¥äžãšãªããŸãããªãå°æ°ã¯å®ç°å¢ãšç°ãªããä»åã®å
容ãšé¢ä¿ãªãéšåãªã©ã¯çç¥ããŠããŸãã æ¬¡ã«ãä»åã®æ¬é¡ãšãªã Proxy å±€ã®æ§æã«ã€ããŠè§ŠããããšæããŸãã Proxy å±€ã®æ§æ Proxy å±€ã®æ¹éçã¯ãŸãšãããšä»¥äžã®éãã§ãproxy å
ã®åçå€å®ãšåå解決ããç®æããã¢ãšãªããŸãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãèµ·åæã«èªèº«ã®å
éš IP ãš Tag ã«èšå®ããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã« Route53 ã® PrivateDNS ã«ç»é²ãã ã¯ã©ã€ã¢ã³ãèå¥ ID ã a-client ã®å Žåãa-client.local ã®ããã«ç»é² Proxy 局㮠Nginx ã¯ã¯ã©ã€ã¢ã³ãèªèšŒãè¡ãããªã¯ãšã¹ããã¹ããåãåºããã¯ã©ã€ã¢ã³ãèå¥ ID ãå
ã«è»¢éå
Endpoint ãçæããbackend ã« proxy ãã App å±€ã®ã€ã³ã¹ã¿ã³ã¹ã¯åçã«å¢ããããããªã¯ãšã¹ãæã«åå解決ãããïŒã€ã³ã¹ã¿ã³ã¹ãå¢ãã床ã«èªåã§ Nginx ã® conf ãç·šéããããšãæ€èšãããè¿œå æ°ãèªãããconf ããµãããããã®ããªãããããšããæããããæ¢ããŸããïŒ Nginx 㯠backend ãå¢ããŠãèµ·åãã£ã±ãªãã§åçã«åå解決ããŠåäœããããã£ããããlua-nginx-module ãå°å
¥ã balancer_by_lua ãã£ã¬ã¯ãã£ããš lua-resty-dns ã¢ãžã¥ãŒã«ã䜿çšããããšãšããæ§ç¯ã®æéã®é¢ä¿ãã OpenResty ãå°å
¥ããããšã«ããŸããã lua-nginx-module ã䜿çšãã conf ãã¡ã€ã« conf ãã¡ã€ã«å
šäœãšããŠã¯ä»¥äžãšãªããŸãïŒé¢ä¿ãªãç®æã¯çããŠããŸãïŒããã€ã³ããšèšèŒããéšåã«ã€ããŠã®èª¬æã¯åŸè¿°ããŸãã http { upstream app { # ãã€ã³ã 1. # Private DNS ã§èšå®ãã IPïŒCNAME ã«èšå®ïŒãå
ã«åç Routing balancer_by_lua_block { local balancer = require "ngx.balancer" local host = ngx . ctx . upstream_server . cname local port = '8888' local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } } server { listen 443 ssl; set $ proxy_upstream_host '' ; set $ proxy_upstream_domain '.local' ; location ^~ /api/ { rewrite_by_lua_block { -- path ããã¯ã©ã€ã¢ã³ãèå¥ ID ãååŸããPrivate DNS ã«èšå®ãããã¡ã€ã³ãçæ -- https://example.com/<id>/api ãšãã圢åŒã®ãªã¯ãšã¹ãããã<id>.local ãšãããã¡ã€ã³ãçæã㊠-- ngx.var.proxy_upstream_host 倿°ã«æ ŒçŽ local ngx_re = require "ngx.re" local res , err = ngx_re . split ( ngx . var . request_uri , "/" , nil , { pos = 0 }) local id = res[3] ngx.var. proxy_upstream_host = id..ngx.var.proxy_upstream_domain; -- resolver èšå® local resolver = require "resty.dns.resolver" local r, err = resolver:new{ nameservers = {{ "x.x.x.x" , 53}}, -- 䜿çšãã nameserver } if not r then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- ãã€ã³ã 2. -- çæãããã¡ã€ã³åïŒ<id>.localïŒãå
ã«åå解決ããååŸããçµæã ngx.ctx ã«ã»ãã -- ïŒbalancer_by_lua_block ã§äœ¿çšããïŒ local answers, err = r:query(ngx.var.proxy_upstream_host, { qtype = r.TYPE_CNAME }) if not answers then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end if answers.errcode then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end ngx.ctx.upstream_server = answers[1] } proxy_set_header Host $ host ; proxy_set_header X-Real-IP $ remote_addr ; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $ scheme ; -- https://<id>.local/api ã« proxy rewrite ^/api/(.+)$ /api/ break; proxy_pass https://app; } } } ãã€ã³ã 1. åç Routing balancer.set_current_peer ã«ãŠ proxy å
ãåçã«èšå®ããŸãã host éšåã«ã¯ãã¡ã€ã³ãçŽæ¥æå®ããããšãã§ããªãããããã€ã³ã 2. ã§ ngx.ctx ã«ã»ãããã DNS ã®å€ãã IPïŒRoute53 ã« CNAME ã¬ã³ãŒããšããŠèšå®ããŠããïŒãæå®ããŠããŸãã balancer_by_lua_block { local balancer = require "ngx.balancer" -- ngx.ctx ã«ã»ããããŠãããPrivate DNS ããååŸããå
éš IP ãã»ãã local host = ngx . ctx . upstream_server . cname local port = '8888' -- proxy å
ã»ãããhost ã«ãã¡ã€ã³ã¯çŽæ¥æå®ã§ããªã local ok , err = balancer . set_current_peer ( host , port ) if not ok then return ngx . exit ( 500 ) end } 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ãã€ã³ã 2. åçåå解決 r:query ã«ãŠãçæãããã¡ã€ã³åïŒ <id>.local ïŒãåãåãããŸãã r éšå㯠resolver:new ã§ nameserver ãæå®ãã resolver ãšãªããŸãã ãªããnameserver ã«æå®ãã IP ã¯ä»å㯠Route53 ã® Private DNS ãæå®ãããããå€éš nameserver ã§ã¯ãªãããŒã«ã«ã® nameserverïŒ10.0.0.2 ãªã©ïŒãæå®ããããšã«ãªããŸãã åãåããçµæã® answers éšå㯠Lua table 圢åŒã®é
åãšãªããŸããä»åã®äŸã§ãããšå¯Ÿè±¡ã¯ 1 ä»¶ãšãªãã®ã§ããã®å€ã balancer_by_lua_block ã§äœ¿çšããããã« ngx.ctx ã«ã»ããããŠããŸãã local answers , err = r : query ( ngx . var . proxy_upstream_host , { qtype = r . TYPE_CNAME }) if not answers then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end if answers . errcode then ngx . exit ( ngx . HTTP_INTERNAL_SERVER_ERROR ) end ngx . ctx . upstream_server = answers [ 1 ] 詳现ã«ã€ããŠã¯ OpenResty ã® ããã¥ã¡ã³ã ãåç
§ããŠãã ãã ä»åã®ãŸãšã upstream å
ãåçã«å€å®ã㊠proxy ãããšããèŠä»¶ã¯ããããç¡ããããããŸããããéäžãŸã§ã¯è€éãªæ§æã«ãªãããã ãªããšããããããŠããŸããããçµæãšããŠã¯ãããªãã«ã·ã³ãã«ã«ãªã£ãããªãšæããŸãã仿Žãªãã NginxïŒãš lua moduleïŒã¯æè»ã§è¯ãåºæ¥ãŠããªããšããææ³ã§ããã åŸç·šã¯ App å±€ã«ã€ããŠãEC2 ãš Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ãããã«ã€ããŠå
±æãããŠããã ããã°ãšæããŸãã ã¯ã©ã€ã¢ã³ãèªèšŒãš Path Based Routing ãå¿
èŠãªãµãŒãã AWS ã§æ§ç¯ïŒåŸç·šïŒApp å±€ïŒ | MEDLEY Developer Portal ä»åã®å
容ã«ã€ã㊠ã¡ãã¬ãŒéçºæ¬éšã®ç°äžã§ãã å
æ¥ãProxy å±€ã Elastic Beanstalk äžã® Nginx ã§ãApp å±€ã EC2 ã€ã³ã¹ã¿ã³ã¹ã§æ§ç¯ããæ©äŒããããŸãããããã ãèŠããšãšãŠãæ®éã«èŠããŸãããå¶çŽãã... developer.medley.jp åèãªã³ã¯ æ§ç¯ã«ããããäžèšèšäºãåèã«ãããŠããã ããŸãããããããšãããããŸãã Nginx balancer_by_luaã®è©±ãšupstreamåå解決ã®è©± - Qiita balancer_by_lua_xxxxx ãã€ã®éã«ãã1 lua-nginx-module ã« balancer_by_lua_xxx ãšããæ°ãããã£ã¬ã¯ãã£ããå¢ããŠããŸããã 以äžããã¥ã¡ã³ãããæç²ã http { upstream backend {... qiita.com ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã ã¡ã³ããŒã®ã¹ããŒãªãŒ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ã³ããŒã®ã¹ããŒãªãŒ å®¶æãå人ãç
æ°ã«ãªã£ãæã«æãã®æãå·®ãã®ã¹ãå»çã®åã... www.medley.jp
éçºæ¬éšã®å¹³å±±ã§ããå
æ¥ã瀟å
å匷äŒãTechLunchãã«ãŠç€Ÿå€ã«å
¬éã§ããªãå
容ã®çºè¡šãããŠããŸããŸããã®ã§ããã®ä»£ãããšããŠãåçåŽåçãæäŸãããNDB ãªãŒãã³ããŒã¿ãããªãŒãã³åãã話ã«ã€ããŠãããã°ãæžãããšæããŸãã NDB ãªãŒãã³ããŒã¿ãšã¯? www.mhlw.go.jp äœæã®èæ¯ â ã¬ã»ããæ
å ±ã»ç¹å®å¥èšºçæ
å ±ããŒã¿ããŒã¹ïŒNDBïŒã¯ãæçæ§ãé«ãã¬ã»ããæ
å ±ãããã³æ€æ»å€ãªã©ã®è©³çŽ°ãªæ
å ±ãæããç¹å®å¥èšºçæ
å ±ãå«ãŸããŠãããåœæ°ã®å»çååãè©äŸ¡ããããã§æçšãªããŒã¿ã ãšèããããŠããã â 2011 幎床ãããå»çè²»é©æ£åèšç»çå®ã«è³ããç®ç以å€ã§ã® NDB ããŒã¿ã®å©çšãèªããããããNDB ããŒã¿ã®æ©åŸ®æ§ã®é«ãã«éã¿ãå©çšè
ã«å¯ŸããŠã¯é«ãã¬ãã«ã®ã»ãã¥ãªãã£èŠä»¶ã課ããããã§ãããŒã¿æäŸãè¡ãããŠããã â äžæ¹ã§ãå€ãã®ç ç©¶è
ãå¿
ããã詳现ãªå祚ããŒã¿ãå¿
èŠãšããããã§ã¯ãªããããå€ãã®äººã
ã䜿çšã§ãããããªããããããå®åŒåãããéèšããŒã¿ã NDB ããŒã¿ãããšã«æŽåããããšãéèŠã§ã¯ãªããããšããè°è«ãæèè
äŒè°çã§ãªãããŠããã â NDB ã®æ°éæäŸã«é¢ããè°è«ã§ãããã¬ã»ããæ
å ±çã®æäŸã«é¢ããã¯ãŒãã³ã°ã°ã«ãŒããããã®å ±åã§ã¯ãæ±çšæ§ãé«ãæ§ã
ãªããŒãºã«äžå®çšåºŠå¿ãããåºç€çãªéèšè¡šãäœæããå
¬è¡šããŠããããšããããé©åœã§ããããšããææãã¿ãããã äœæã®ç®ç â å€ãã®äººã
ã NDB ããŒã¿ã«åºã¥ããä¿å¥å»çã«é¢ããç¥èŠã«æ¥ããããšãåºæ¥ããããNDB ããŒã¿ãçšããŠåºç€çãªéèšè¡šãäœæããããã§ãå
¬è¡šããã â NDB ããŒã¿ã«åºã¥ããå»çã®æäŸå®æ
ãç¹å®å¥èšºçã®çµæããããããã瀺ãã èŠã¯çããããç
é¢ã«è¡ã£ãæã«ãããæçްæžã«èšèŒãããŠããå蚺ããç¹ã倿¥èšºçæããç¹ã®ãããªããŒã¿ãå人æ
å ±ãå¿ååãããç¶æ
ã§åéããã®çµ±èšããŒã¿ãäžè¬ã«å
¬éããããšãã£ããšããã§ããããã ãã®ãããªããŒã¿ããªãŒãã³ã«ãªã£ãŠããããšã¯ãšãŠãæçŸ©ã®ããããšã ãšæããŸãããå
¬éã«ãŸã§ããã€ããé¢ä¿è
ã®èŠåŽãæ³åãããŸãããããããã®ãããªç»æçãªããŒã¿æäŸã§ã¯ãããŸãããExcel ãã¡ã€ã«ã§ã®æäŸãšãªã£ãŠããããã€å å·¥ããã¥ããããŒã¿æ§é ã«ãªã£ãŠãããããããŒã¿ã现ããã¿ãŠã¿ãããšãããšéåžžã«æéãããããšããåé¡ããããŸãã NDB ãªãŒãã³ããŒã¿ã®ãªãŒãã³å ããã§ NDB ãªãŒãã³ããŒã¿ãšããŠå
¬éãããŠãã Excel ãã¡ã€ã«ãå å·¥ããDB ã«æ ŒçŽã BI ããŒã«ïŒ Redash ïŒããåç
§ãããããã«ããŠã¿ãŸããã 1. ããŒã¿å å·¥ & DB åã蟌㿠å
¬éãµã€ã ã«ããå»ç§èšºçè¡çºã«é¢ãã Excel ãã¡ã€ã«ãååŸãããã°ããŒãã«ãšããŠãããããã©ãŒãããã«å€æã DB ã«åã蟌ãã 倿å å€æåŸ *************************** 1. row *************************** id: 1 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: all revision: 2014 prefecture: sex: age: score: 251700771 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 2. row *************************** id: 2 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 0ïœ4 æ³ score: 13158090 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 3. row *************************** id: 3 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 5ïœ9 æ³ score: 12444947 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 2. ããŒã¿ã®åç
§ 倿ããããŒã¿ãåã蟌ãã DB ã Redash ããåç
§ãåæãããããŒã¿ãååŸããããã®ã¯ãšãªãæžããŠããã·ã¥ããŒãåã NDB ãªãŒãã³ããŒã¿ã®æŽ»çšäŸ 以äžã«ç°¡åãªããŒã¿æŽ»çšã®ãµã³ãã«ãèŒããŸãããå»è¬èšºçè¡çºã ãã§ãªãç¹å®å¥èšºãè¬å€ã®ããŒã¿ã䜿ããšããå°ãé¢çœãæ°ä»ãããããããããŸããã ãããã«ããããã®ããã«å å·¥å¯èœãªåœ¢ã§ã®ããŒã¿æäŸããããªãŒãã³ããŒã¿æäŸã®äŸ¡å€ã ãšæãã®ã§ããã®ãããªä»çµã¿ãå éããã°è¯ããªãšæããŸãã 0-4 æ³ ç·æ§ 蚺çè¡çºç¹æ° 90 æ³ä»¥äž ç·æ§ 蚺çè¡çºç¹æ° 140023350 èç»ããæµåé£ç¹æ»Žæ³šå
¥ éœéåºçå¥ 150086210 è§èç§»æ€è¡ å¹Žéœ¡å¥ ãŸãšã 以äžãNDB ãªãŒãã³ããŒã¿ããªãŒãã³åããŠã¿ã話ã«ã€ããŠæžããŠã¿ãŸããã ãã®ããã«.go.jp ããæäŸãããããŒã¿ã¯äžè¬çã« Excel ã PDF ã§ã®ãã¡ã€ã«æäŸãåºæ¬ã§ãã€ã³ã¿ãŒããããµãŒãã¹ã®ããã« API ã®ãããªåœ¢ã§æäŸãããããšã¯ãããŸããããã£ãã貎éãªããŒã¿ãæäŸãããŠããã«ãé¢ããããããã IT ã·ã¹ãã ãšé£åãã¥ããããšã§ã掻çšãããªãç¶æ³ã«ãªã£ãŠããã®ã¯ãšãŠãæ®å¿µãªããšã«æããŸãã Code for America ã®äºäŸã§ã¯ãªãã§ããããã£ãšã€ã³ã¿ãŒãããç³»ã®äººæããã®ãããªåãçµã¿ã«å
¥ã蟌ãã§ããããã«ãªãã°ãããåççã§ã¹ããŒããªä»çµã¿ãå éããæ¥çå
šäœã® IT åãå éããã®ã§ã¯ãªãã§ããããã ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã www.medley.jp
éçºæ¬éšã®å¹³å±±ã§ããå
æ¥ã瀟å
å匷äŒãTechLunchãã«ãŠç€Ÿå€ã«å
¬éã§ããªãå
容ã®çºè¡šãããŠããŸããŸããã®ã§ããã®ä»£ãããšããŠãåçåŽåçãæäŸãããNDB ãªãŒãã³ããŒã¿ãããªãŒãã³åãã話ã«ã€ããŠãããã°ãæžãããšæããŸãã NDB ãªãŒãã³ããŒã¿ãšã¯? www.mhlw.go.jp äœæã®èæ¯ â ã¬ã»ããæ
å ±ã»ç¹å®å¥èšºçæ
å ±ããŒã¿ããŒã¹ïŒNDBïŒã¯ãæçæ§ãé«ãã¬ã»ããæ
å ±ãããã³æ€æ»å€ãªã©ã®è©³çŽ°ãªæ
å ±ãæããç¹å®å¥èšºçæ
å ±ãå«ãŸããŠãããåœæ°ã®å»çååãè©äŸ¡ããããã§æçšãªããŒã¿ã ãšèããããŠããã â 2011 幎床ãããå»çè²»é©æ£åèšç»çå®ã«è³ããç®ç以å€ã§ã® NDB ããŒã¿ã®å©çšãèªããããããNDB ããŒã¿ã®æ©åŸ®æ§ã®é«ãã«éã¿ãå©çšè
ã«å¯ŸããŠã¯é«ãã¬ãã«ã®ã»ãã¥ãªãã£èŠä»¶ã課ããããã§ãããŒã¿æäŸãè¡ãããŠããã â äžæ¹ã§ãå€ãã®ç ç©¶è
ãå¿
ããã詳现ãªå祚ããŒã¿ãå¿
èŠãšããããã§ã¯ãªããããå€ãã®äººã
ã䜿çšã§ãããããªããããããå®åŒåãããéèšããŒã¿ã NDB ããŒã¿ãããšã«æŽåããããšãéèŠã§ã¯ãªããããšããè°è«ãæèè
äŒè°çã§ãªãããŠããã â NDB ã®æ°éæäŸã«é¢ããè°è«ã§ãããã¬ã»ããæ
å ±çã®æäŸã«é¢ããã¯ãŒãã³ã°ã°ã«ãŒããããã®å ±åã§ã¯ãæ±çšæ§ãé«ãæ§ã
ãªããŒãºã«äžå®çšåºŠå¿ãããåºç€çãªéèšè¡šãäœæããå
¬è¡šããŠããããšããããé©åœã§ããããšããææãã¿ãããã äœæã®ç®ç â å€ãã®äººã
ã NDB ããŒã¿ã«åºã¥ããä¿å¥å»çã«é¢ããç¥èŠã«æ¥ããããšãåºæ¥ããããNDB ããŒã¿ãçšããŠåºç€çãªéèšè¡šãäœæããããã§ãå
¬è¡šããã â NDB ããŒã¿ã«åºã¥ããå»çã®æäŸå®æ
ãç¹å®å¥èšºçã®çµæããããããã瀺ãã èŠã¯çããããç
é¢ã«è¡ã£ãæã«ãããæçްæžã«èšèŒãããŠããå蚺ããç¹ã倿¥èšºçæããç¹ã®ãããªããŒã¿ãå人æ
å ±ãå¿ååãããç¶æ
ã§åéããã®çµ±èšããŒã¿ãäžè¬ã«å
¬éããããšãã£ããšããã§ããããã ãã®ãããªããŒã¿ããªãŒãã³ã«ãªã£ãŠããããšã¯ãšãŠãæçŸ©ã®ããããšã ãšæããŸãããå
¬éã«ãŸã§ããã€ããé¢ä¿è
ã®èŠåŽãæ³åãããŸãããããããã®ãããªç»æçãªããŒã¿æäŸã§ã¯ãããŸãããExcel ãã¡ã€ã«ã§ã®æäŸãšãªã£ãŠããããã€å å·¥ããã¥ããããŒã¿æ§é ã«ãªã£ãŠãããããããŒã¿ã现ããã¿ãŠã¿ãããšãããšéåžžã«æéãããããšããåé¡ããããŸãã NDB ãªãŒãã³ããŒã¿ã®ãªãŒãã³å ããã§ NDB ãªãŒãã³ããŒã¿ãšããŠå
¬éãããŠãã Excel ãã¡ã€ã«ãå å·¥ããDB ã«æ ŒçŽã BI ããŒã«ïŒ Redash ïŒããåç
§ãããããã«ããŠã¿ãŸããã 1. ããŒã¿å å·¥ & DB åã蟌㿠å
¬éãµã€ã ã«ããå»ç§èšºçè¡çºã«é¢ãã Excel ãã¡ã€ã«ãååŸãããã°ããŒãã«ãšããŠãããããã©ãŒãããã«å€æã DB ã«åã蟌ãã 倿å å€æåŸ *************************** 1. row *************************** id: 1 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: all revision: 2014 prefecture: sex: age: score: 251700771 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 2. row *************************** id: 2 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 0ïœ4 æ³ score: 13158090 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 3. row *************************** id: 3 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 5ïœ9 æ³ score: 12444947 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 2. ããŒã¿ã®åç
§ 倿ããããŒã¿ãåã蟌ãã DB ã Redash ããåç
§ãåæãããããŒã¿ãååŸããããã®ã¯ãšãªãæžããŠããã·ã¥ããŒãåã NDB ãªãŒãã³ããŒã¿ã®æŽ»çšäŸ 以äžã«ç°¡åãªããŒã¿æŽ»çšã®ãµã³ãã«ãèŒããŸãããå»è¬èšºçè¡çºã ãã§ãªãç¹å®å¥èšºãè¬å€ã®ããŒã¿ã䜿ããšããå°ãé¢çœãæ°ä»ãããããããããŸããã ãããã«ããããã®ããã«å å·¥å¯èœãªåœ¢ã§ã®ããŒã¿æäŸããããªãŒãã³ããŒã¿æäŸã®äŸ¡å€ã ãšæãã®ã§ããã®ãããªä»çµã¿ãå éããã°è¯ããªãšæããŸãã 0-4 æ³ ç·æ§ 蚺çè¡çºç¹æ° 90 æ³ä»¥äž ç·æ§ 蚺çè¡çºç¹æ° 140023350 èç»ããæµåé£ç¹æ»Žæ³šå
¥ éœéåºçå¥ 150086210 è§èç§»æ€è¡ å¹Žéœ¡å¥ ãŸãšã 以äžãNDB ãªãŒãã³ããŒã¿ããªãŒãã³åããŠã¿ã話ã«ã€ããŠæžããŠã¿ãŸããã ãã®ããã«.go.jp ããæäŸãããããŒã¿ã¯äžè¬çã« Excel ã PDF ã§ã®ãã¡ã€ã«æäŸãåºæ¬ã§ãã€ã³ã¿ãŒããããµãŒãã¹ã®ããã« API ã®ãããªåœ¢ã§æäŸãããããšã¯ãããŸããããã£ãã貎éãªããŒã¿ãæäŸãããŠããã«ãé¢ããããããã IT ã·ã¹ãã ãšé£åãã¥ããããšã§ã掻çšãããªãç¶æ³ã«ãªã£ãŠããã®ã¯ãšãŠãæ®å¿µãªããšã«æããŸãã Code for America ã®äºäŸã§ã¯ãªãã§ããããã£ãšã€ã³ã¿ãŒãããç³»ã®äººæããã®ãããªåãçµã¿ã«å
¥ã蟌ãã§ããããã«ãªãã°ãããåççã§ã¹ããŒããªä»çµã¿ãå éããæ¥çå
šäœã® IT åãå éããã®ã§ã¯ãªãã§ããããã ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã www.medley.jp
éçºæ¬éšã®å¹³å±±ã§ããå
æ¥ã瀟å
å匷äŒãTechLunchãã«ãŠç€Ÿå€ã«å
¬éã§ããªãå
容ã®çºè¡šãããŠããŸããŸããã®ã§ããã®ä»£ãããšããŠãåçåŽåçãæäŸãããNDB ãªãŒãã³ããŒã¿ãããªãŒãã³åãã話ã«ã€ããŠãããã°ãæžãããšæããŸãã NDB ãªãŒãã³ããŒã¿ãšã¯? www.mhlw.go.jp äœæã®èæ¯ â ã¬ã»ããæ
å ±ã»ç¹å®å¥èšºçæ
å ±ããŒã¿ããŒã¹ïŒNDBïŒã¯ãæçæ§ãé«ãã¬ã»ããæ
å ±ãããã³æ€æ»å€ãªã©ã®è©³çŽ°ãªæ
å ±ãæããç¹å®å¥èšºçæ
å ±ãå«ãŸããŠãããåœæ°ã®å»çååãè©äŸ¡ããããã§æçšãªããŒã¿ã ãšèããããŠããã â 2011 幎床ãããå»çè²»é©æ£åèšç»çå®ã«è³ããç®ç以å€ã§ã® NDB ããŒã¿ã®å©çšãèªããããããNDB ããŒã¿ã®æ©åŸ®æ§ã®é«ãã«éã¿ãå©çšè
ã«å¯ŸããŠã¯é«ãã¬ãã«ã®ã»ãã¥ãªãã£èŠä»¶ã課ããããã§ãããŒã¿æäŸãè¡ãããŠããã â äžæ¹ã§ãå€ãã®ç ç©¶è
ãå¿
ããã詳现ãªå祚ããŒã¿ãå¿
èŠãšããããã§ã¯ãªããããå€ãã®äººã
ã䜿çšã§ãããããªããããããå®åŒåãããéèšããŒã¿ã NDB ããŒã¿ãããšã«æŽåããããšãéèŠã§ã¯ãªããããšããè°è«ãæèè
äŒè°çã§ãªãããŠããã â NDB ã®æ°éæäŸã«é¢ããè°è«ã§ãããã¬ã»ããæ
å ±çã®æäŸã«é¢ããã¯ãŒãã³ã°ã°ã«ãŒããããã®å ±åã§ã¯ãæ±çšæ§ãé«ãæ§ã
ãªããŒãºã«äžå®çšåºŠå¿ãããåºç€çãªéèšè¡šãäœæããå
¬è¡šããŠããããšããããé©åœã§ããããšããææãã¿ãããã äœæã®ç®ç â å€ãã®äººã
ã NDB ããŒã¿ã«åºã¥ããä¿å¥å»çã«é¢ããç¥èŠã«æ¥ããããšãåºæ¥ããããNDB ããŒã¿ãçšããŠåºç€çãªéèšè¡šãäœæããããã§ãå
¬è¡šããã â NDB ããŒã¿ã«åºã¥ããå»çã®æäŸå®æ
ãç¹å®å¥èšºçã®çµæããããããã瀺ãã èŠã¯çããããç
é¢ã«è¡ã£ãæã«ãããæçްæžã«èšèŒãããŠããå蚺ããç¹ã倿¥èšºçæããç¹ã®ãããªããŒã¿ãå人æ
å ±ãå¿ååãããç¶æ
ã§åéããã®çµ±èšããŒã¿ãäžè¬ã«å
¬éããããšãã£ããšããã§ããããã ãã®ãããªããŒã¿ããªãŒãã³ã«ãªã£ãŠããããšã¯ãšãŠãæçŸ©ã®ããããšã ãšæããŸãããå
¬éã«ãŸã§ããã€ããé¢ä¿è
ã®èŠåŽãæ³åãããŸãããããããã®ãããªç»æçãªããŒã¿æäŸã§ã¯ãããŸãããExcel ãã¡ã€ã«ã§ã®æäŸãšãªã£ãŠããããã€å å·¥ããã¥ããããŒã¿æ§é ã«ãªã£ãŠãããããããŒã¿ã现ããã¿ãŠã¿ãããšãããšéåžžã«æéãããããšããåé¡ããããŸãã NDB ãªãŒãã³ããŒã¿ã®ãªãŒãã³å ããã§ NDB ãªãŒãã³ããŒã¿ãšããŠå
¬éãããŠãã Excel ãã¡ã€ã«ãå å·¥ããDB ã«æ ŒçŽã BI ããŒã«ïŒ Redash ïŒããåç
§ãããããã«ããŠã¿ãŸããã 1. ããŒã¿å å·¥ & DB åã蟌㿠å
¬éãµã€ã ã«ããå»ç§èšºçè¡çºã«é¢ãã Excel ãã¡ã€ã«ãååŸãããã°ããŒãã«ãšããŠãããããã©ãŒãããã«å€æã DB ã«åã蟌ãã 倿å å€æåŸ *************************** 1. row *************************** id: 1 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: all revision: 2014 prefecture: sex: age: score: 251700771 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 2. row *************************** id: 2 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 0ïœ4 æ³ score: 13158090 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 3. row *************************** id: 3 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 5ïœ9 æ³ score: 12444947 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 2. ããŒã¿ã®åç
§ 倿ããããŒã¿ãåã蟌ãã DB ã Redash ããåç
§ãåæãããããŒã¿ãååŸããããã®ã¯ãšãªãæžããŠããã·ã¥ããŒãåã NDB ãªãŒãã³ããŒã¿ã®æŽ»çšäŸ 以äžã«ç°¡åãªããŒã¿æŽ»çšã®ãµã³ãã«ãèŒããŸãããå»è¬èšºçè¡çºã ãã§ãªãç¹å®å¥èšºãè¬å€ã®ããŒã¿ã䜿ããšããå°ãé¢çœãæ°ä»ãããããããããŸããã ãããã«ããããã®ããã«å å·¥å¯èœãªåœ¢ã§ã®ããŒã¿æäŸããããªãŒãã³ããŒã¿æäŸã®äŸ¡å€ã ãšæãã®ã§ããã®ãããªä»çµã¿ãå éããã°è¯ããªãšæããŸãã 0-4 æ³ ç·æ§ 蚺çè¡çºç¹æ° 90 æ³ä»¥äž ç·æ§ 蚺çè¡çºç¹æ° 140023350 èç»ããæµåé£ç¹æ»Žæ³šå
¥ éœéåºçå¥ 150086210 è§èç§»æ€è¡ å¹Žéœ¡å¥ ãŸãšã 以äžãNDB ãªãŒãã³ããŒã¿ããªãŒãã³åããŠã¿ã話ã«ã€ããŠæžããŠã¿ãŸããã ãã®ããã«.go.jp ããæäŸãããããŒã¿ã¯äžè¬çã« Excel ã PDF ã§ã®ãã¡ã€ã«æäŸãåºæ¬ã§ãã€ã³ã¿ãŒããããµãŒãã¹ã®ããã« API ã®ãããªåœ¢ã§æäŸãããããšã¯ãããŸããããã£ãã貎éãªããŒã¿ãæäŸãããŠããã«ãé¢ããããããã IT ã·ã¹ãã ãšé£åãã¥ããããšã§ã掻çšãããªãç¶æ³ã«ãªã£ãŠããã®ã¯ãšãŠãæ®å¿µãªããšã«æããŸãã Code for America ã®äºäŸã§ã¯ãªãã§ããããã£ãšã€ã³ã¿ãŒãããç³»ã®äººæããã®ãããªåãçµã¿ã«å
¥ã蟌ãã§ããããã«ãªãã°ãããåççã§ã¹ããŒããªä»çµã¿ãå éããæ¥çå
šäœã® IT åãå éããã®ã§ã¯ãªãã§ããããã ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã www.medley.jp
éçºæ¬éšã®å¹³å±±ã§ããå
æ¥ã瀟å
å匷äŒãTechLunchãã«ãŠç€Ÿå€ã«å
¬éã§ããªãå
容ã®çºè¡šãããŠããŸããŸããã®ã§ããã®ä»£ãããšããŠãåçåŽåçãæäŸãããNDB ãªãŒãã³ããŒã¿ãããªãŒãã³åãã話ã«ã€ããŠãããã°ãæžãããšæããŸãã NDB ãªãŒãã³ããŒã¿ãšã¯? www.mhlw.go.jp äœæã®èæ¯ â ã¬ã»ããæ
å ±ã»ç¹å®å¥èšºçæ
å ±ããŒã¿ããŒã¹ïŒNDBïŒã¯ãæçæ§ãé«ãã¬ã»ããæ
å ±ãããã³æ€æ»å€ãªã©ã®è©³çŽ°ãªæ
å ±ãæããç¹å®å¥èšºçæ
å ±ãå«ãŸããŠãããåœæ°ã®å»çååãè©äŸ¡ããããã§æçšãªããŒã¿ã ãšèããããŠããã â 2011 幎床ãããå»çè²»é©æ£åèšç»çå®ã«è³ããç®ç以å€ã§ã® NDB ããŒã¿ã®å©çšãèªããããããNDB ããŒã¿ã®æ©åŸ®æ§ã®é«ãã«éã¿ãå©çšè
ã«å¯ŸããŠã¯é«ãã¬ãã«ã®ã»ãã¥ãªãã£èŠä»¶ã課ããããã§ãããŒã¿æäŸãè¡ãããŠããã â äžæ¹ã§ãå€ãã®ç ç©¶è
ãå¿
ããã詳现ãªå祚ããŒã¿ãå¿
èŠãšããããã§ã¯ãªããããå€ãã®äººã
ã䜿çšã§ãããããªããããããå®åŒåãããéèšããŒã¿ã NDB ããŒã¿ãããšã«æŽåããããšãéèŠã§ã¯ãªããããšããè°è«ãæèè
äŒè°çã§ãªãããŠããã â NDB ã®æ°éæäŸã«é¢ããè°è«ã§ãããã¬ã»ããæ
å ±çã®æäŸã«é¢ããã¯ãŒãã³ã°ã°ã«ãŒããããã®å ±åã§ã¯ãæ±çšæ§ãé«ãæ§ã
ãªããŒãºã«äžå®çšåºŠå¿ãããåºç€çãªéèšè¡šãäœæããå
¬è¡šããŠããããšããããé©åœã§ããããšããææãã¿ãããã äœæã®ç®ç â å€ãã®äººã
ã NDB ããŒã¿ã«åºã¥ããä¿å¥å»çã«é¢ããç¥èŠã«æ¥ããããšãåºæ¥ããããNDB ããŒã¿ãçšããŠåºç€çãªéèšè¡šãäœæããããã§ãå
¬è¡šããã â NDB ããŒã¿ã«åºã¥ããå»çã®æäŸå®æ
ãç¹å®å¥èšºçã®çµæããããããã瀺ãã èŠã¯çããããç
é¢ã«è¡ã£ãæã«ãããæçްæžã«èšèŒãããŠããå蚺ããç¹ã倿¥èšºçæããç¹ã®ãããªããŒã¿ãå人æ
å ±ãå¿ååãããç¶æ
ã§åéããã®çµ±èšããŒã¿ãäžè¬ã«å
¬éããããšãã£ããšããã§ããããã ãã®ãããªããŒã¿ããªãŒãã³ã«ãªã£ãŠããããšã¯ãšãŠãæçŸ©ã®ããããšã ãšæããŸãããå
¬éã«ãŸã§ããã€ããé¢ä¿è
ã®èŠåŽãæ³åãããŸãããããããã®ãããªç»æçãªããŒã¿æäŸã§ã¯ãããŸãããExcel ãã¡ã€ã«ã§ã®æäŸãšãªã£ãŠããããã€å å·¥ããã¥ããããŒã¿æ§é ã«ãªã£ãŠãããããããŒã¿ã现ããã¿ãŠã¿ãããšãããšéåžžã«æéãããããšããåé¡ããããŸãã NDB ãªãŒãã³ããŒã¿ã®ãªãŒãã³å ããã§ NDB ãªãŒãã³ããŒã¿ãšããŠå
¬éãããŠãã Excel ãã¡ã€ã«ãå å·¥ããDB ã«æ ŒçŽã BI ããŒã«ïŒ Redash ïŒããåç
§ãããããã«ããŠã¿ãŸããã 1. ããŒã¿å å·¥ & DB åã蟌㿠å
¬éãµã€ã ã«ããå»ç§èšºçè¡çºã«é¢ãã Excel ãã¡ã€ã«ãååŸãããã°ããŒãã«ãšããŠãããããã©ãŒãããã«å€æã DB ã«åã蟌ãã 倿å å€æåŸ *************************** 1. row *************************** id: 1 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: all revision: 2014 prefecture: sex: age: score: 251700771 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 2. row *************************** id: 2 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 0ïœ4 æ³ score: 13158090 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 3. row *************************** id: 3 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 5ïœ9 æ³ score: 12444947 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 2. ããŒã¿ã®åç
§ 倿ããããŒã¿ãåã蟌ãã DB ã Redash ããåç
§ãåæãããããŒã¿ãååŸããããã®ã¯ãšãªãæžããŠããã·ã¥ããŒãåã NDB ãªãŒãã³ããŒã¿ã®æŽ»çšäŸ 以äžã«ç°¡åãªããŒã¿æŽ»çšã®ãµã³ãã«ãèŒããŸãããå»è¬èšºçè¡çºã ãã§ãªãç¹å®å¥èšºãè¬å€ã®ããŒã¿ã䜿ããšããå°ãé¢çœãæ°ä»ãããããããããŸããã ãããã«ããããã®ããã«å å·¥å¯èœãªåœ¢ã§ã®ããŒã¿æäŸããããªãŒãã³ããŒã¿æäŸã®äŸ¡å€ã ãšæãã®ã§ããã®ãããªä»çµã¿ãå éããã°è¯ããªãšæããŸãã 0-4 æ³ ç·æ§ 蚺çè¡çºç¹æ° 90 æ³ä»¥äž ç·æ§ 蚺çè¡çºç¹æ° 140023350 èç»ããæµåé£ç¹æ»Žæ³šå
¥ éœéåºçå¥ 150086210 è§èç§»æ€è¡ å¹Žéœ¡å¥ ãŸãšã 以äžãNDB ãªãŒãã³ããŒã¿ããªãŒãã³åããŠã¿ã話ã«ã€ããŠæžããŠã¿ãŸããã ãã®ããã«.go.jp ããæäŸãããããŒã¿ã¯äžè¬çã« Excel ã PDF ã§ã®ãã¡ã€ã«æäŸãåºæ¬ã§ãã€ã³ã¿ãŒããããµãŒãã¹ã®ããã« API ã®ãããªåœ¢ã§æäŸãããããšã¯ãããŸããããã£ãã貎éãªããŒã¿ãæäŸãããŠããã«ãé¢ããããããã IT ã·ã¹ãã ãšé£åãã¥ããããšã§ã掻çšãããªãç¶æ³ã«ãªã£ãŠããã®ã¯ãšãŠãæ®å¿µãªããšã«æããŸãã Code for America ã®äºäŸã§ã¯ãªãã§ããããã£ãšã€ã³ã¿ãŒãããç³»ã®äººæããã®ãããªåãçµã¿ã«å
¥ã蟌ãã§ããããã«ãªãã°ãããåççã§ã¹ããŒããªä»çµã¿ãå éããæ¥çå
šäœã® IT åãå éããã®ã§ã¯ãªãã§ããããã ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã www.medley.jp
éçºæ¬éšã®å¹³å±±ã§ããå
æ¥ã瀟å
å匷äŒãTechLunchãã«ãŠç€Ÿå€ã«å
¬éã§ããªãå
容ã®çºè¡šãããŠããŸããŸããã®ã§ããã®ä»£ãããšããŠãåçåŽåçãæäŸãããNDB ãªãŒãã³ããŒã¿ãããªãŒãã³åãã話ã«ã€ããŠãããã°ãæžãããšæããŸãã NDB ãªãŒãã³ããŒã¿ãšã¯? www.mhlw.go.jp äœæã®èæ¯ â ã¬ã»ããæ
å ±ã»ç¹å®å¥èšºçæ
å ±ããŒã¿ããŒã¹ïŒNDBïŒã¯ãæçæ§ãé«ãã¬ã»ããæ
å ±ãããã³æ€æ»å€ãªã©ã®è©³çŽ°ãªæ
å ±ãæããç¹å®å¥èšºçæ
å ±ãå«ãŸããŠãããåœæ°ã®å»çååãè©äŸ¡ããããã§æçšãªããŒã¿ã ãšèããããŠããã â 2011 幎床ãããå»çè²»é©æ£åèšç»çå®ã«è³ããç®ç以å€ã§ã® NDB ããŒã¿ã®å©çšãèªããããããNDB ããŒã¿ã®æ©åŸ®æ§ã®é«ãã«éã¿ãå©çšè
ã«å¯ŸããŠã¯é«ãã¬ãã«ã®ã»ãã¥ãªãã£èŠä»¶ã課ããããã§ãããŒã¿æäŸãè¡ãããŠããã â äžæ¹ã§ãå€ãã®ç ç©¶è
ãå¿
ããã詳现ãªå祚ããŒã¿ãå¿
èŠãšããããã§ã¯ãªããããå€ãã®äººã
ã䜿çšã§ãããããªããããããå®åŒåãããéèšããŒã¿ã NDB ããŒã¿ãããšã«æŽåããããšãéèŠã§ã¯ãªããããšããè°è«ãæèè
äŒè°çã§ãªãããŠããã â NDB ã®æ°éæäŸã«é¢ããè°è«ã§ãããã¬ã»ããæ
å ±çã®æäŸã«é¢ããã¯ãŒãã³ã°ã°ã«ãŒããããã®å ±åã§ã¯ãæ±çšæ§ãé«ãæ§ã
ãªããŒãºã«äžå®çšåºŠå¿ãããåºç€çãªéèšè¡šãäœæããå
¬è¡šããŠããããšããããé©åœã§ããããšããææãã¿ãããã äœæã®ç®ç â å€ãã®äººã
ã NDB ããŒã¿ã«åºã¥ããä¿å¥å»çã«é¢ããç¥èŠã«æ¥ããããšãåºæ¥ããããNDB ããŒã¿ãçšããŠåºç€çãªéèšè¡šãäœæããããã§ãå
¬è¡šããã â NDB ããŒã¿ã«åºã¥ããå»çã®æäŸå®æ
ãç¹å®å¥èšºçã®çµæããããããã瀺ãã èŠã¯çããããç
é¢ã«è¡ã£ãæã«ãããæçްæžã«èšèŒãããŠããå蚺ããç¹ã倿¥èšºçæããç¹ã®ãããªããŒã¿ãå人æ
å ±ãå¿ååãããç¶æ
ã§åéããã®çµ±èšããŒã¿ãäžè¬ã«å
¬éããããšãã£ããšããã§ããããã ãã®ãããªããŒã¿ããªãŒãã³ã«ãªã£ãŠããããšã¯ãšãŠãæçŸ©ã®ããããšã ãšæããŸãããå
¬éã«ãŸã§ããã€ããé¢ä¿è
ã®èŠåŽãæ³åãããŸãããããããã®ãããªç»æçãªããŒã¿æäŸã§ã¯ãããŸãããExcel ãã¡ã€ã«ã§ã®æäŸãšãªã£ãŠããããã€å å·¥ããã¥ããããŒã¿æ§é ã«ãªã£ãŠãããããããŒã¿ã现ããã¿ãŠã¿ãããšãããšéåžžã«æéãããããšããåé¡ããããŸãã NDB ãªãŒãã³ããŒã¿ã®ãªãŒãã³å ããã§ NDB ãªãŒãã³ããŒã¿ãšããŠå
¬éãããŠãã Excel ãã¡ã€ã«ãå å·¥ããDB ã«æ ŒçŽã BI ããŒã«ïŒ Redash ïŒããåç
§ãããããã«ããŠã¿ãŸããã 1. ããŒã¿å å·¥ & DB åã蟌㿠å
¬éãµã€ã ã«ããå»ç§èšºçè¡çºã«é¢ãã Excel ãã¡ã€ã«ãååŸãããã°ããŒãã«ãšããŠãããããã©ãŒãããã«å€æã DB ã«åã蟌ãã 倿å å€æåŸ *************************** 1. row *************************** id: 1 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: all revision: 2014 prefecture: sex: age: score: 251700771 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 2. row *************************** id: 2 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 0ïœ4 æ³ score: 13158090 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 3. row *************************** id: 3 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 5ïœ9 æ³ score: 12444947 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 2. ããŒã¿ã®åç
§ 倿ããããŒã¿ãåã蟌ãã DB ã Redash ããåç
§ãåæãããããŒã¿ãååŸããããã®ã¯ãšãªãæžããŠããã·ã¥ããŒãåã NDB ãªãŒãã³ããŒã¿ã®æŽ»çšäŸ 以äžã«ç°¡åãªããŒã¿æŽ»çšã®ãµã³ãã«ãèŒããŸãããå»è¬èšºçè¡çºã ãã§ãªãç¹å®å¥èšºãè¬å€ã®ããŒã¿ã䜿ããšããå°ãé¢çœãæ°ä»ãããããããããŸããã ãããã«ããããã®ããã«å å·¥å¯èœãªåœ¢ã§ã®ããŒã¿æäŸããããªãŒãã³ããŒã¿æäŸã®äŸ¡å€ã ãšæãã®ã§ããã®ãããªä»çµã¿ãå éããã°è¯ããªãšæããŸãã 0-4 æ³ ç·æ§ 蚺çè¡çºç¹æ° 90 æ³ä»¥äž ç·æ§ 蚺çè¡çºç¹æ° 140023350 èç»ããæµåé£ç¹æ»Žæ³šå
¥ éœéåºçå¥ 150086210 è§èç§»æ€è¡ å¹Žéœ¡å¥ ãŸãšã 以äžãNDB ãªãŒãã³ããŒã¿ããªãŒãã³åããŠã¿ã話ã«ã€ããŠæžããŠã¿ãŸããã ãã®ããã«.go.jp ããæäŸãããããŒã¿ã¯äžè¬çã« Excel ã PDF ã§ã®ãã¡ã€ã«æäŸãåºæ¬ã§ãã€ã³ã¿ãŒããããµãŒãã¹ã®ããã« API ã®ãããªåœ¢ã§æäŸãããããšã¯ãããŸããããã£ãã貎éãªããŒã¿ãæäŸãããŠããã«ãé¢ããããããã IT ã·ã¹ãã ãšé£åãã¥ããããšã§ã掻çšãããªãç¶æ³ã«ãªã£ãŠããã®ã¯ãšãŠãæ®å¿µãªããšã«æããŸãã Code for America ã®äºäŸã§ã¯ãªãã§ããããã£ãšã€ã³ã¿ãŒãããç³»ã®äººæããã®ãããªåãçµã¿ã«å
¥ã蟌ãã§ããããã«ãªãã°ãããåççã§ã¹ããŒããªä»çµã¿ãå éããæ¥çå
šäœã® IT åãå éããã®ã§ã¯ãªãã§ããããã ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã www.medley.jp
éçºæ¬éšã®å¹³å±±ã§ããå
æ¥ã瀟å
å匷äŒãTechLunchãã«ãŠç€Ÿå€ã«å
¬éã§ããªãå
容ã®çºè¡šãããŠããŸããŸããã®ã§ããã®ä»£ãããšããŠãåçåŽåçãæäŸãããNDB ãªãŒãã³ããŒã¿ãããªãŒãã³åãã話ã«ã€ããŠãããã°ãæžãããšæããŸãã NDB ãªãŒãã³ããŒã¿ãšã¯? www.mhlw.go.jp äœæã®èæ¯ â ã¬ã»ããæ
å ±ã»ç¹å®å¥èšºçæ
å ±ããŒã¿ããŒã¹ïŒNDBïŒã¯ãæçæ§ãé«ãã¬ã»ããæ
å ±ãããã³æ€æ»å€ãªã©ã®è©³çŽ°ãªæ
å ±ãæããç¹å®å¥èšºçæ
å ±ãå«ãŸããŠãããåœæ°ã®å»çååãè©äŸ¡ããããã§æçšãªããŒã¿ã ãšèããããŠããã â 2011 幎床ãããå»çè²»é©æ£åèšç»çå®ã«è³ããç®ç以å€ã§ã® NDB ããŒã¿ã®å©çšãèªããããããNDB ããŒã¿ã®æ©åŸ®æ§ã®é«ãã«éã¿ãå©çšè
ã«å¯ŸããŠã¯é«ãã¬ãã«ã®ã»ãã¥ãªãã£èŠä»¶ã課ããããã§ãããŒã¿æäŸãè¡ãããŠããã â äžæ¹ã§ãå€ãã®ç ç©¶è
ãå¿
ããã詳现ãªå祚ããŒã¿ãå¿
èŠãšããããã§ã¯ãªããããå€ãã®äººã
ã䜿çšã§ãããããªããããããå®åŒåãããéèšããŒã¿ã NDB ããŒã¿ãããšã«æŽåããããšãéèŠã§ã¯ãªããããšããè°è«ãæèè
äŒè°çã§ãªãããŠããã â NDB ã®æ°éæäŸã«é¢ããè°è«ã§ãããã¬ã»ããæ
å ±çã®æäŸã«é¢ããã¯ãŒãã³ã°ã°ã«ãŒããããã®å ±åã§ã¯ãæ±çšæ§ãé«ãæ§ã
ãªããŒãºã«äžå®çšåºŠå¿ãããåºç€çãªéèšè¡šãäœæããå
¬è¡šããŠããããšããããé©åœã§ããããšããææãã¿ãããã äœæã®ç®ç â å€ãã®äººã
ã NDB ããŒã¿ã«åºã¥ããä¿å¥å»çã«é¢ããç¥èŠã«æ¥ããããšãåºæ¥ããããNDB ããŒã¿ãçšããŠåºç€çãªéèšè¡šãäœæããããã§ãå
¬è¡šããã â NDB ããŒã¿ã«åºã¥ããå»çã®æäŸå®æ
ãç¹å®å¥èšºçã®çµæããããããã瀺ãã èŠã¯çããããç
é¢ã«è¡ã£ãæã«ãããæçްæžã«èšèŒãããŠããå蚺ããç¹ã倿¥èšºçæããç¹ã®ãããªããŒã¿ãå人æ
å ±ãå¿ååãããç¶æ
ã§åéããã®çµ±èšããŒã¿ãäžè¬ã«å
¬éããããšãã£ããšããã§ããããã ãã®ãããªããŒã¿ããªãŒãã³ã«ãªã£ãŠããããšã¯ãšãŠãæçŸ©ã®ããããšã ãšæããŸãããå
¬éã«ãŸã§ããã€ããé¢ä¿è
ã®èŠåŽãæ³åãããŸãããããããã®ãããªç»æçãªããŒã¿æäŸã§ã¯ãããŸãããExcel ãã¡ã€ã«ã§ã®æäŸãšãªã£ãŠããããã€å å·¥ããã¥ããããŒã¿æ§é ã«ãªã£ãŠãããããããŒã¿ã现ããã¿ãŠã¿ãããšãããšéåžžã«æéãããããšããåé¡ããããŸãã NDB ãªãŒãã³ããŒã¿ã®ãªãŒãã³å ããã§ NDB ãªãŒãã³ããŒã¿ãšããŠå
¬éãããŠãã Excel ãã¡ã€ã«ãå å·¥ããDB ã«æ ŒçŽã BI ããŒã«ïŒ Redash ïŒããåç
§ãããããã«ããŠã¿ãŸããã 1. ããŒã¿å å·¥ & DB åã蟌㿠å
¬éãµã€ã ã«ããå»ç§èšºçè¡çºã«é¢ãã Excel ãã¡ã€ã«ãååŸãããã°ããŒãã«ãšããŠãããããã©ãŒãããã«å€æã DB ã«åã蟌ãã 倿å å€æåŸ *************************** 1. row *************************** id: 1 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: all revision: 2014 prefecture: sex: age: score: 251700771 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 2. row *************************** id: 2 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 0ïœ4 æ³ score: 13158090 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 *************************** 3. row *************************** id: 3 practice_category_code: A000 practice_category_name: å蚺æ practice_code: 111000110 practice_name: å蚺 practice_type: 倿¥ target: sex_age revision: 2014 prefecture: sex: ç·æ§ age: 5ïœ9 æ³ score: 12444947 created_at: 0000-00-00 00:00:00 updated_at: 0000-00-00 00:00:00 2. ããŒã¿ã®åç
§ 倿ããããŒã¿ãåã蟌ãã DB ã Redash ããåç
§ãåæãããããŒã¿ãååŸããããã®ã¯ãšãªãæžããŠããã·ã¥ããŒãåã NDB ãªãŒãã³ããŒã¿ã®æŽ»çšäŸ 以äžã«ç°¡åãªããŒã¿æŽ»çšã®ãµã³ãã«ãèŒããŸãããå»è¬èšºçè¡çºã ãã§ãªãç¹å®å¥èšºãè¬å€ã®ããŒã¿ã䜿ããšããå°ãé¢çœãæ°ä»ãããããããããŸããã ãããã«ããããã®ããã«å å·¥å¯èœãªåœ¢ã§ã®ããŒã¿æäŸããããªãŒãã³ããŒã¿æäŸã®äŸ¡å€ã ãšæãã®ã§ããã®ãããªä»çµã¿ãå éããã°è¯ããªãšæããŸãã 0-4 æ³ ç·æ§ 蚺çè¡çºç¹æ° 90 æ³ä»¥äž ç·æ§ 蚺çè¡çºç¹æ° 140023350 èç»ããæµåé£ç¹æ»Žæ³šå
¥ éœéåºçå¥ 150086210 è§èç§»æ€è¡ å¹Žéœ¡å¥ ãŸãšã 以äžãNDB ãªãŒãã³ããŒã¿ããªãŒãã³åããŠã¿ã話ã«ã€ããŠæžããŠã¿ãŸããã ãã®ããã«.go.jp ããæäŸãããããŒã¿ã¯äžè¬çã« Excel ã PDF ã§ã®ãã¡ã€ã«æäŸãåºæ¬ã§ãã€ã³ã¿ãŒããããµãŒãã¹ã®ããã« API ã®ãããªåœ¢ã§æäŸãããããšã¯ãããŸããããã£ãã貎éãªããŒã¿ãæäŸãããŠããã«ãé¢ããããããã IT ã·ã¹ãã ãšé£åãã¥ããããšã§ã掻çšãããªãç¶æ³ã«ãªã£ãŠããã®ã¯ãšãŠãæ®å¿µãªããšã«æããŸãã Code for America ã®äºäŸã§ã¯ãªãã§ããããã£ãšã€ã³ã¿ãŒãããç³»ã®äººæããã®ãããªåãçµã¿ã«å
¥ã蟌ãã§ããããã«ãªãã°ãããåççã§ã¹ããŒããªä»çµã¿ãå éããæ¥çå
šäœã® IT åãå éããã®ã§ã¯ãªãã§ããããã ãç¥ãã ã¡ãã¬ãŒã§ã¯ãå»åž«ãã¡ãã€ãããªã³ã©ã€ã³å»çäºå
žã MEDLEY ãããªã³ã©ã€ã³èšºçã¢ããªã CLINICS ããå»çä»è·ã®æ±äººãµã€ãã ãžã§ãã¡ãã¬ãŒ ããå£ã³ãã§æ¢ããä»è·æœèšã®æ€çŽ¢ãµã€ãã ä»è·ã®ã»ãã ããªã©ã®ãããã¯ããæäŸããŠããŸãããããã®ãµãŒãã¹ã®æ¡å€§ãåããŠããã®æé·ãæ¯ãããšã³ãžãã¢ã»ãã¶ã€ããŒãåéããŠããŸãã ã¡ãã¬ãŒã§äžç·ã«å»çäœéšãå€ãããããã¯ãäœãã«é¢ããããæ¹ã®ãé£çµ¡ãåŸ
ã¡ããŠãããŸãã www.medley.jp