概要
最近github actionsが楽しいのでaws環境でteraform + ansible実行してみた。
EC2を構築し、httpdをインストールする所まで実施。
目次
・事前準備
・ディレクトリ構成
・バケット作成
・IAMユーザ作成
・terraformコード作成
・ansible コード作成
・github actions 作成
・githu actions 実行結果
##事前準備
- EC2のIPの自動取得にdyanamic inventoryが使用できること
##ディレクトリ構成
├── README.md
├── ansible
│ ├── ansible.cfg
│ ├── ec2.ini
│ ├── ec2.py
│ ├── roles
│ │ ├── common
│ │ │ ├── files
│ │ │ │ └── main.yml
│ │ │ └── tasks
│ │ └── nginx
│ │ ├── files
│ │ └── tasks
│ │ └── main.yml
│ ├── sandbox.yml
└── terraform
├── backend.tf
├── data.tf
├── main.tf
├── output
├── output.tf
├── provider.tf
└── variables.tf
S3バケット作成
tfstate保存用のバケットを作成する。
% aws s3 mb s3://tf-sandbox-masa3521
make_bucket: tf-sandbox-masa3521
IAMユーザ作成
terraform,ansibleの実行用のIAMユーザを作成する。
EC2とS3、key系はパラメータストアから取得するので必要な権限を付与する。
% aws iam create-user --user-name cicd_user
{
"User": {
"Path": "/",
"UserName": "cicd_user",
"UserId": "***************",
"Arn": "arn:aws:iam::***************:user/cicd_user",
"CreateDate": "2020-05-21T15:05:18Z"
}
}
% aws iam create-access-key --user-name cicd_user
{
"AccessKey": {
"UserName": "cicd_user",
"AccessKeyId": "***************",
"Status": "Active",
"SecretAccessKey": "***************",
"CreateDate": "2020-05-22T00:42:37Z"
}
}
% aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --user-name cicd_user
% aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --user-name cicd_user
% aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess --user-name cicd_user
% aws iam list-attached-user-policies --user-name cicd_user
{
"AttachedPolicies": [
{
"PolicyName": "AmazonEC2FullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
},
{
"PolicyName": "AmazonS3FullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonS3FullAccess"
},
{
"PolicyName": "AmazonSSMReadOnlyAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess"
}
]
}
key作成
EC2に設定する公開鍵/秘密鍵を作成し、作成したものをパラメータストアに登録する。
% ssh-keygen -t rsa -b 4096
% aws ssm put-parameter --name "publickey" \
--type SecureString \
--value "$(cat id_rsa.pub)"
{
"Version": 1,
"Tier": "Standard"
}
% aws ssm put-parameter --name "pravatekey" \
--type SecureString \
--value "$(cat id_rsa)"
{
"Version": 1,
"Tier": "Standard"
}
terraformコード作成
- data.tfで公開鍵をパラメータストアから取得
- backend.tfでtfstateをリモートで管理
- output.tfでセキュリティーグループのgroupidをファイルに出力 ※後のgithub-actionsで使用
provider "aws" {
profile = "default"
version = "= 2.61"
region = "ap-northeast-1"
}
terraform {
backend "s3" {
bucket = "tf-sandbox-masa3521"
region = "ap-northeast-1"
key = "terraform.tfstate"
encrypt = true
}
}
data "aws_ssm_parameter" "publickey" {
name = "publickey"
with_decryption = true
}
variable "region" {
default = "ap-northeast-1"
}
variable "system" {
default = "sandbox"
}
resource "local_file" "sgroupid" {
filename = "./group_id"
content = aws_security_group.sandboxSG.id
}
resource "aws_vpc" "sandboxVPC" {
cidr_block = "10.1.0.0/16"
instance_tenancy = "default"
enable_dns_support = "true"
enable_dns_hostnames = "false"
tags = {
Name = var.system
Env = terraform.workspace
}
}
resource "aws_route_table" "sanbboxRT" {
vpc_id = aws_vpc.sandboxVPC.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.sandboxGW.id
}
tags = {
Name = var.system
Env = terraform.workspace
}
}
resource "aws_subnet" "sandboxSUBNET" {
vpc_id = aws_vpc.sandboxVPC.id
cidr_block = "10.1.0.0/24"
tags = {
Name = var.system
Env = terraform.workspace
}
}
resource "aws_internet_gateway" "sandboxGW" {
vpc_id = aws_vpc.sandboxVPC.id
tags = {
Name = var.system
Env = terraform.workspace
}
}
resource "aws_route_table_association" "sandboxRTA" {
subnet_id = aws_subnet.sandboxSUBNET.id
route_table_id = aws_route_table.sanbboxRT.id
}
resource "aws_security_group" "sandboxSG" {
name = "sandboxSG"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.sandboxVPC.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = var.system
Env = terraform.workspace
}
}
resource "aws_key_pair" "publickey" {
key_name = "key"
public_key = data.aws_ssm_parameter.publickey.value
tags = {
Name = var.system
Env = terraform.workspace
}
}
resource "aws_instance" "sandboxinstance" {
key_name = aws_key_pair.publickey.id
ami = "ami-0f310fced6141e627"
instance_type = "t2.nano"
vpc_security_group_ids = [
aws_security_group.sandboxSG.id
]
subnet_id = aws_subnet.sandboxSUBNET.id
associate_public_ip_address = "true"
tags = {
Name = var.system
Env = terraform.workspace
}
}
ansible 作成
[defaults]
deprecation_warnings = False
remote_user = ec2-user
private_key_file = ./privatekey
host_key_checking = False
- hosts: tag_Name_sandbox
roles:
- htted
---
- name: install apache
yum:
name: httpd
state: present
become: true
- name: Start httpd
service:
name: httpd
state: started
enabled: yes
become: true
github-actions作成
- 実行の為にsecretsの登録が必要
- IPを自動で取得するためDynamic Inventoryで取得する。
- ansble実行の為秘密鍵のダウンロード
- ansible実行前にセキュリティーグループに自分のIPを登録、実行後に自分のIPを削除
secrets登録
name: Terraform deploy to Azure
on:
push:
branches:
- master
jobs:
terraform-ansible:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 0.12.9
- name: Terraform Init
run: terraform init
working-directory: ${{ github.workspace }}/terraform
- name: Terraform select
run: terraform workspace select dev
working-directory: ${{ github.workspace }}/terraform
- name: Terraform Format
run: terraform fmt -check
working-directory: ${{ github.workspace }}/terraform
- name: Terraform Plan
run: terraform plan
working-directory: ${{ github.workspace }}/terraform
- name: Terraform Apply
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
run: terraform apply -auto-approve
working-directory: ${{ github.workspace }}/terraform
- name: Set up Python 3.7
uses: actions/setup-python@v2
with:
python-version: 3.7
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install boto ansible==2.9.2
- name: Download privatekey
run: aws ssm get-parameter --name "privatekey" --with-decryption | jq -r .Parameter.Value > ./privatekey
working-directory: ${{ github.workspace }}/ansible
- name: modify permission privatekey
run: chmod 400 ./privatekey
working-directory: ${{ github.workspace }}/ansible
- name: open sg
run: aws ec2 authorize-security-group-ingress --group-id "$(cat ../terraform/group_id)" --protocol tcp --port 22 --cidr `curl inet-ip.info`/32
working-directory: ${{ github.workspace }}/ansible
- name: exec ansible
run: ansible-playbook -i ec2.py sandbox.yml
working-directory: ${{ github.workspace }}/ansible
- name: close sg
run: aws ec2 revoke-security-group-ingress --group-id "$(cat ../terraform/group_id)" --protocol tcp --port 22 --cidr `curl inet-ip.info`/32
working-directory: ${{ github.workspace }}/ansible
github-actions 結果
[参考]
https://www.terraform.io/docs/github-actions/setup-terraform.html
https://github.com/aws-actions/configure-aws-credentials
https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html