設定値の指定
設定値の指定
手順に必要な設定値を変数に格納をします。
1. リソースファイルディレクトリ
リソースファイルディレクトリを指定します。
変数の設定:
DIR_CLOUDFORMATION_RESOURCE="${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/resources"
2. CloudFormationテンプレート名
CloudFormationテンプレート名を指定します。
変数の設定:
CLOUDFORMATION_TEMPLATE_NAME='handson-cli-cfn-ec2-VolumeAttachment'
3. CloudFormationテンプレートの説明
CloudFormationテンプレートの説明を指定します。
変数の設定:
CLOUDFORMATION_TEMPLATE_DESCRIPTION='Template for handson-cli-cfn-ec2-VolumeAttachment.'
4. テンプレートファイルディレクトリ
テンプレートファイルディレクトリを指定します。
変数の設定:
DIR_CLOUDFORMATION_TEMPLATE="${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment"
ディレクトリが存在することを確認します。
コマンド:
ls -d ${DIR_CLOUDFORMATION_TEMPLATE}
結果(例:存在する場合):
${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment
存在しない場合は作成します。
コマンド:
mkdir -p ${DIR_CLOUDFORMATION_TEMPLATE}
5. テンプレートファイル名の指定
テンプレートファイル名の指定します。
変数の設定:
FILE_CLOUDFORMATION_TEMPLATE="${DIR_CLOUDFORMATION_TEMPLATE}/${CLOUDFORMATION_TEMPLATE_NAME}.template" \
&& echo ${FILE_CLOUDFORMATION_TEMPLATE}
結果(例):
${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment.template
設定値の確認
各変数に正しい設定値が格納されていることを確認しながら保存します。
変数の確認:
cat << END
# 1. DIR_CLOUDFORMATION_RESOURCE:"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/resources"
DIR_CLOUDFORMATION_RESOURCE="${DIR_CLOUDFORMATION_RESOURCE}"
# 2. CLOUDFORMATION_TEMPLATE_NAME:"handson-cli-cfn-ec2-VolumeAttachment"
CLOUDFORMATION_TEMPLATE_NAME="${CLOUDFORMATION_TEMPLATE_NAME}"
# 3. CLOUDFORMATION_TEMPLATE_DESCRIPTION:"Template for handson-cli-cfn-ec2-VolumeAttachment."
CLOUDFORMATION_TEMPLATE_DESCRIPTION="${CLOUDFORMATION_TEMPLATE_DESCRIPTION}"
# 4. DIR_CLOUDFORMATION_TEMPLATE:"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment"
DIR_CLOUDFORMATION_TEMPLATE="${DIR_CLOUDFORMATION_TEMPLATE}"
# 5. FILE_CLOUDFORMATION_TEMPLATE:"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment.template"
FILE_CLOUDFORMATION_TEMPLATE="${FILE_CLOUDFORMATION_TEMPLATE}"
END
下段の変数が入っていない、もしくは上段と同等の値が入っていない場合は、それぞれの手順番号に戻って変数の設定を行います。
処理の実行
CloudFormationテンプレート共通部分を作成します。
変数の確認:
cat << END
# FILE_CLOUDFORMATION_TEMPLATE:"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment.template"
FILE_CLOUDFORMATION_TEMPLATE="${FILE_CLOUDFORMATION_TEMPLATE}"
# CLOUDFORMATION_TEMPLATE_DESCRIPTION:"Template for handson-cli-cfn-ec2-VolumeAttachment."
CLOUDFORMATION_TEMPLATE_DESCRIPTION="${CLOUDFORMATION_TEMPLATE_DESCRIPTION}"
END
コマンド:
cat << EOF > ${FILE_CLOUDFORMATION_TEMPLATE}
AWSTemplateFormatVersion: 2010-09-09
Description:
${CLOUDFORMATION_TEMPLATE_DESCRIPTION}
EOF
cat ${FILE_CLOUDFORMATION_TEMPLATE}
結果(例):
AWSTemplateFormatVersion: 2010-09-09
Description:
Template for handson-cli-cfn-ec2-VolumeAttachment.
CloudFormationテンプレートにリソース部分を追加します。
コマンド:
echo 'Resources:' >> ${FILE_CLOUDFORMATION_TEMPLATE}
for i in $( ls ${DIR_CLOUDFORMATION_RESOURCE}/*.txt ); do \
cat $i | sed '/^$/d' >> ${FILE_CLOUDFORMATION_TEMPLATE}; \
echo '' >> ${FILE_CLOUDFORMATION_TEMPLATE} \
; done
cat ${FILE_CLOUDFORMATION_TEMPLATE}
結果(例):
AWSTemplateFormatVersion: 2010-09-09
Description:
Template for handson-cli
Resources:
Igw0:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Join
- ''
- - !Ref AWS::StackName
- '-igw'
IgwAttachment0:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref Igw0
VpcId: !Ref Vpc0
InstanceProfile0:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: !Join
- ''
- - !Ref AWS::StackName
- '-instance-profile'
Path: /handson-cli/
Roles:
- !Ref Role0
LogsGroup0:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /var/log/secure
Role0:
Type: AWS::IAM::Role
Properties:
Path: /handson-cli/
RoleName: !Join
- ''
- - !Ref AWS::StackName
- '-role'
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
RouteDefault:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTable0
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref Igw0
RouteTable0:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc0
Tags:
- Key: Name
Value: !Join
- ''
- - !Ref AWS::StackName
- '-routetable'
SecurityGroup0:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref Vpc0
GroupDescription: for handson-cli-cfn-ec2-Instance.
GroupName: !Join
- ''
- - !Ref AWS::StackName
- '-sg'
SGIngress0Cidr:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt SecurityGroup0.GroupId
Description: Rule for handson-cli-cfn-ec2-Instance.
IpProtocol: tcp
FromPort: 22022
ToPort: 22022
CidrIp: 0.0.0.0/0
Subnet0:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc0
CidrBlock: 10.0.3.0/24
Tags:
- Key: Name
Value: !Join
- ''
- - !Ref AWS::StackName
- '-subnet'
AvailabilityZone: ap-northeast-1c
SubnetRouteTableAttachment0:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTable0
SubnetId: !Ref Subnet0
Vpc0:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: !Join
- ''
- - !Ref AWS::StackName
- '-vpc'
Instance0:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-09ebacdc178ae23b7
InstanceType: t3.micro
Tags:
- Key: Name
Value: !Ref AWS::StackName
NetworkInterfaces:
- DeviceIndex: "0"
SubnetId: !Ref Subnet0
GroupSet:
- !Ref SecurityGroup0
AssociatePublicIpAddress: "true"
UserData: !Base64 |
#!/bin/bash
# configure sshd
cat << EOF >> /etc/ssh/sshd_config
Port 22022
EOF
systemctl restart sshd.service
# yum
yum update -y
#
# logs agent
#
readonly EC2_METADATA_SECOND='900'
readonly EC2_METADATA_TOKEN=$( \
curl -s \
-X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: ${EC2_METADATA_SECOND}" \
)
readonly EC2_METADATA_HEADER="X-aws-ec2-metadata-token: ${EC2_METADATA_TOKEN}"
readonly EC2_REGION_NAME=$( \
curl -s -H "${EC2_METADATA_HEADER}" \
http://169.254.169.254/latest/meta-data/placement/availability-zone \
| sed -e 's/[a-z]*$//' \
)
# install cloudwatch agent
readonly URL_DOWNLOAD_LINK="https://s3.${EC2_REGION_NAME}.amazonaws.com/amazoncloudwatch-agent-${EC2_REGION_NAME}/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm"
cd /tmp/
wget ${URL_DOWNLOAD_LINK}
rpm -U ./amazon-cloudwatch-agent.rpm
# setup cloudwatch agent
readonly LOGS_CONF='/opt/aws/amazon-cloudwatch-agent/etc/logs.conf'
# logs.conf
cat << EOF > ${LOGS_CONF}
{
"agent": {
"logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/secure",
"log_group_name": "/var/log/secure",
"timezone": "UTC"
}
]
}
},
"log_stream_name": "{instance_id}",
"force_flush_interval" : 15
}
}
EOF
# start cloudwatch agent
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:${LOGS_CONF} \
-s
#
# disk format (sdh)
#
DEVICE_FILE_NAME="sdh"
MOUNT_POINT_NAME="/mnt-handson-cli-ebs"
DISK_TYPE='xfs'
DISK_TARGET="/dev/${DEVICE_FILE_NAME}"
# format disk
mkfs \
-t ${DISK_TYPE} \
${DISK_TARGET}
# make mount point
mkdir ${MOUNT_POINT_NAME}
# update fstab
cp /etc/fstab /etc/fstab.$(date +%s)
DEVICE_LINK_NAME=$( \
file -s ${DISK_TARGET} \
| sed "s/^.*\`//" \
| sed "s/'$//" \
)
DISK_UUID=$( \
sudo blkid \
| grep /dev/${DEVICE_LINK_NAME} \
| sed "s/^.*UUID=\"//" \
| sed "s/\".*$//" \
)
DISK_TYPE_TARGET=$( \
sudo blkid \
| grep /dev/${DEVICE_LINK_NAME} \
| sed "s/^.*TYPE=\"//" \
| sed "s/\".*$//" \
)
if [ ! $( grep ${DISK_UUID} /etc/fstab ) ]; then
sh -c "echo \"UUID=${DISK_UUID} ${MOUNT_POINT_NAME} ${DISK_TYPE_TARGET} defaults,nofail 0 2\" >> /etc/fstab"
fi
# mount disk
mount ${MOUNT_POINT_NAME}
chown ec2-user:ec2-user ${MOUNT_POINT_NAME}
KeyName: handson-cli-cfn-ec2-VolumeAttachment-keypair
IamInstanceProfile: !Ref InstanceProfile0
Volume0:
Type: AWS::EC2::Volume
Properties:
AvailabilityZone: ap-northeast-1c
VolumeType: gp3
Size: 8
Tags:
- Key: Name
Value: !Ref AWS::StackName
VolumeAttachment0:
Type: AWS::EC2::VolumeAttachment
Properties:
VolumeId: !Ref Volume0
InstanceId: !Ref Instance0
Device: /dev/sdh
完了確認
本手順の主処理は、以下の完了条件を満たしたときに成功したものとします。
完了条件1: CloudFormationテンプレート"handson-cli-cfn-ec2-VolumeAttachment"が存在する。
「CloudFormationテンプレート"handson-cli-cfn-ec2-VolumeAttachment"が存在する。」ことを確認します。
コマンド:
ls ${FILE_CLOUDFORMATION_TEMPLATE}
結果(例):
${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment.template
完了条件2: CloudFormationテンプレート"handson-cli-cfn-ec2-VolumeAttachment"がYAMLフォーマットとして正常である。
「CloudFormationテンプレート"handson-cli-cfn-ec2-VolumeAttachment"がYAMLフォーマットとして正常である。」ことを確認します。
コマンド:
yamllint ${FILE_CLOUDFORMATION_TEMPLATE}
結果(例):