1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Terraformを始めよう②【インフラエンジニアへの道2日目】

Posted at

インフラエンジニアへの道2日目です:hatched_chick:

今回取り組むこと

  • Session Managerを利用してみる
  • IAMロールをTerraformで設定する
  • セキュリティグループをTerraformで設定する

この記事内での目標

AWS Systems Manager Session Managerを使用して、Amazon EC2インスタンスにSSH接続せずにアクセスし、Webサーバー(Apache HTTP Server)をセットアップする。

1. インスタンスの設定

IAM Roleを設定して、AWS Systems Manager Session Managerから操作が出来るようにしてみます。
iam.tfを作成し、IAMRoleに必要な定義を記述します。
このIAMRoleはEC2インスタンスに紐づけるため、EC2サービスからのアクセス許可を定義しました。

data "aws_iam_policy_document" "instance-assume-role-policy"{
    statement {
        actions = ["sts:AssumRole"]

        principals = {
            type        = "Service"
            identifiers = ["ec2.amazonaws.com"]
        }
    }
}

これは信頼ポリシーと呼ばれるもので、IAM Roleが何からのアクセスを引き受けるかを定義します。
最初にdataと記載しています。これは参照専用でリソースの作成や削除は行わず、外部リソースの情報を取得してTerraform上で利用することができます。
1日目の ec2.tf でresourceと記載しています。これはAWSリソースを定義し、作成や削除を行います。
次にIAM Roleを定義します。

resource "aws_iam_role" "demo"{
    name = "demo_role"
    assume_role_policy = data.aws_iam_policy_document.instance_assume-role-policy.json
}

assume_role_policyの行で、先ほど定義した信頼ポリシーの情報を参照しています。
続いてIAM Policyを定義します。
AWSの事前定義済ポリシーであるAmazonSSMMnagedInstanceCoredataを使って参照し、ARN(※)を取得して、Roleに紐づけます。
※ARN…Amazon Resource Name.AWSのリソースを一意に識別するための識別子(ID)
一般的なARNの形式:arn:partition:service:region:account-id:resource
各部分の意味:

部分 説明
arn すべてのARNに共通のプレフィックス
partition AWSのパーティション(通常 aws)
service リソースのサービス(例: iam, s3, ec2)
region リソースのリージョン(グローバルなら空)
account-id AWSアカウントID(AWS管理のものは aws)
resource リソース識別子(サービスごとに異なる)
data "aws_iam_policy" "ssm_core"{
    name = "AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy_attachment" "demo" {
    role = aws_iam_role.demo.name
    policy_arn = data.aws_iam_policy.ssm_core.arn
}

次にインスタンスプロファイルを定義します。
インスタンスプロファイルはIAM RoleとEC2インスタンスを紐づけるコネクタのようなものです。

resource "aws_iam_instance_profile" "demo" {
    name = "demo_role"
    role = aws_iam_role.demo.name
}

ここまでで、iam.tfは以下のようになりました。

iam.tf
data "aws_iam_policy_document" "instance-assume-role-policy"{
    statement {
        actions = ["sts:AssumeRole"]

        principals {
            type        = "Service"
            identifiers = ["ec2.amazonaws.com"]
        }
    }
}

resource "aws_iam_role" "demo"{
    name = "demo_role"
    assume_role_policy = data.aws_iam_policy_document.instance-assume-role-policy.json
}

data "aws_iam_policy" "ssm_core"{
    name = "AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy_attachment" "demo" {
    role = aws_iam_role.demo.name
    policy_arn = data.aws_iam_policy.ssm_core.arn
}


resource "aws_iam_instance_profile" "demo" {
    name = "demo_role"
    role = aws_iam_role.demo.name
}

ec2.tfでインスタンスプロファイルを使用するように定義を編集します。

ec2.tf
resource "aws_instance" "example" {
  ami           = "ami-09896cc5f96ec689a"  # Amazon Linux 2 AMI
  instance_type = "t2.micro"  # t2.micro(無料枠対象)
  
  #この行を追加
  aws_iam_instance_profile = aws_iam_instance_profile.demo.name
  
  tags = {
    Name = "tf_demo"
  }
}

これで準備OKです。

2. インスタンスの再作成

planapplyを実行し、リソースを作成します。

terraform plan
terraform apply

EC2インスタンスが再作成されました。
image.png
Session Managerのコンソールを開きます。正しく設定できている場合は、ターゲットインスタンスに作成したインスタンスが表示されて、セッションを開始することができます。
image.png
※1日目で使っていたAMI(ami-00561c77487da40c1)だとSSM AgentがインストールされていなかったためAMIをami-09896cc5f96ec689aに変更しました。

3. Webサーバの起動

ターゲットインスタンスを選択して、「Start Session」からセッションを開始します。
セッションマネージャーにコマンドを打ってみます。

sudo yum install -y httpd
sudo systemctl start httpd

image.png
Webサーバを起動しましたが、ポートを解放していないためアクセスすることができません。外部からWebサーバへアクセス出来るように、セキュリティグループを作成します。

securitygroup.tf
resource "aws_security_group" "demo" {
    name = "tf_demo"

    tags = {
        Name = "tf_demo"
    }
}

#インバウンドルール
resource "aws_security_group_rule" "ingress_http" {
    type = "ingress"
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cider_blocks = ["0.0.0.0/0"]
    security_group_id = aws_security_group.demo.id
}

#アウトバウンドルール
resource "aws_security_group_rule" "egress_all" {
    type = "egress"
    from_port = 0
    to_port = 0
    protocol = "all"
    cider_blocks = ["0.0.0.0/0"]
    security_group_id = aws_security_group.demo.id
}

plan , applyを実行してセキュリティグループを作成します。

terraform plan
terraform apply

planの結果を見てみるとtfファイルに記載したことが反映されているようです。
image.png

セキュリティグループをEC2に紐づけるため、ec2.tf を編集します。

ec2
resource "aws_instance" "example" {
  ami           = "ami-09896cc5f96ec689a"  # Amazon Linux 2 AMI
  instance_type = "t2.micro"  # t2.micro(無料枠対象)
  iam_instance_profile = aws_iam_instance_profile.demo.name
  
  vpc_security_group_ids = [
    aws_security_group.demo.id
  ]
  
  tags = {
    Name = "tf_demo"
  }
}

再び、plan を実行し、どのような影響があるか確認します。
image.png
元々セキュリティグループの定義がなかったため、デフォルトセキュリティグループが紐づいていましたが、新しく作成したセキュリティグループを使用するように定義したため、changeが出力されました。
リソースの再作成を伴わない変更の場合、変更箇所は~で表示されます。
applyで反映すると、先ほどは見れなかったWebページにApacheのデフォルトページが表示されるようになりました。
image.png
Webサーバの起動に成功したと言っていいでしょう。

4. リソースの再作成を伴う変更

先程リソースの再作成を伴わない変更の動作を確認したので、次はリソースの再作成を伴う動作を確認します。
userdataディレクトリを作成し、Webサーバを起動するスクリプトを配置します。

mkdir userdata
cat <<EOF > userdata/demo.sh
> #!/bin/bash
> yum install -y httpd
> systemctl start httpd
> EOF

ec2.tfを編集し、作成したスクリプトをUserDataとして使用するように定義します。
Terraformのfile関数でスクリプトを渡すことができます。

ec2.tf
resource "aws_instance" "example" {
  ami           = "ami-09896cc5f96ec689a"  # Amazon Linux 2 AMI
  instance_type = "t2.micro"  # t2.micro(無料枠対象)
  iam_instance_profile = aws_iam_instance_profile.demo.name
  
  vpc_security_group_ids = [
    aws_security_group.demo.id
  ]

  user_data = file("./userdata/demo.sh") #この行を追加
  
  tags = {
    Name = "tf_demo"
  }
}

planコマンドを実行して確認してみます。
user_dataが追加されており、public_ipも新しくなるようです。
image.png
今回定義したuserdataはインスタンスの起動時にのみ適用できるパラメータのため、Terraformはリソースを再作成して適用しようとします。
applyを実行して適用します。
image.png
インスタンスが削除、再作成されました。インスタンス起動時にuserdataでWebサーバを起動するように設定したので新しいインスタンスのパブリックIPアドレスにアクセスして動作を確認してみます。
先程と同じApacheのテストページが開きました。
image.png

最後に、忘れずに環境を削除します。

まとめ

この記事では、AWS Systems Manager Session Managerを使用して、Amazon EC2インスタンスにSSH接続せずにアクセスし、Webサーバー(Apache HTTP Server)をセットアップする方法を学びました。

学んだこと

  • AWS Systems Manager Session Manager
    AmazonSSMManagedInstanceCoreポリシーと、IAM Role、インスタンスプロファイルを使用して、EC2インスタンスに対してSession Managerが利用できるように設定しました。
  • IAM Roleの設定
    EC2インスタンスに対してIAM Roleを適用し、そのRoleに適切なポリシー(例えば、SSM用のAmazonSSMManagedInstanceCore)を関連付ける方法を理解しました。
  • セキュリティグループの設定
    セキュリティグループでインバウンドおよびアウトバウンドルールを設定し、EC2インスタンスがHTTPトラフィックを受け取れるようにする方法を学びました。
  • User Dataスクリプト
    EC2インスタンスの起動時に実行されるスクリプトを利用して、インスタンスが自動的にセットアップされるように設定しました。
    Terraformのfile関数を使用して、外部のスクリプトファイルをインスタンスに渡す方法を学びました。
  • Terraformでのインフラ管理
    Terraformでインフラをコードとして管理し、planとapplyコマンドを使ってリソースを作成・変更・削除するプロセスを理解しました。変更を加えた際に、リソースがどのように影響を受けるのか、変更の内容をplanで確認する方法も学びました。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?